{ "info": { "author": "Matthias Urlichs", "author_email": "matthias@urlichs.de", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Framework :: AsyncIO", "Framework :: Trio", "Intended Audience :: Information Technology", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Communications :: Telephony", "Topic :: Software Development :: Testing" ], "description": "===========\nCall tester\n===========\n\nThis program connects to an Asterisk server and performs call tests, i.e.\nit causes one channel to call another and verifies that the call worked.\n\nCallTest implements a small JSON server. You can use it with your favorite\nmonitoring system to check test results, or to manually trigger a test from\nsome web site or via ``curl``.\n\nThis package is a work in progress. Some planned features are not yet implemented.\nAlso, this README needs to be expanded and split up. Volunteers welcome.\n\nConfiguration\n=============\n\nThe configuration is a YAML file and basically looks like this::\n\n links: \n foo:\n channel: \"SIP/foo/{nr}\"\n number: \"+49123456789\"\n bar:\n channel: \"SIP/bar/{nr}\"\n number: \"+49987654321\"\n\n calls:\n ':default:':\n mode: dtmf\n\n foobar:\n src: foo\n dst: bar\n info: \"Check that calling bar from foo works\"\n\n\nSee ``example.cfg`` for a working version. Run ``./ct -c example.cfg\ndumpcfg`` for a copy that's been pre-filled with default values.\n\nLinks\n+++++\n\n``links`` contains the Asterisk channels that CallTest can use.\n\nThese parameters are used when originating a call on the link:\n\n* channel: The dial string used to call out on this channel. ``{nr}`` is a\n placeholder for the destination phone number.\n\nThese parameters are used when answering a call:\n\n* number: The number to dial, when calling this link.\n\nThe ``prio`` value is used for avoiding deadlocks when acquiring links for\nbidirectional tests. If identical, the link's name is used.\n\nThe ':default:' values are applied to all other entries (unless overridden),\nwhich saves you from changing 999 identical entries.\n\n\nCalls\n+++++\n\n``calls`` contains a number of (named) tests.\n\n* src: the source link to use, i.e. to originate the call.\n\n* dst: the destination to use, i.e. to answer the call.\n\n* mode: How to perform a test. See below.\n\n* timeout: Hard limit for a call's duration. If a call exceeds this,\n it is terminated and the test fails.\n\n* url: for answer-only modes, you need a way to cause a call. For now this\n is done by fetching the data at this URL.\n\nThe ':default:' values are applied to all other entries (unless overridden),\nwhich saves you from changing 999 identical entries.\n\nThe ``test`` subheading contains values that are relevant for running\nrepeated tests in the background:\n\n* retry, repeat: seconds to delay until repeating a call, depending on\n whether the previous attempt failed or succeeded.\n\n* warn: number of consecutive failures when the test enters \"warn\" state.\n\n* fail: number of consecutive failures when the test enters \"fail\" state.\n\n* skip: if True, this test can only be triggered manually.\n\n\nModes\n+++++\n\nThe ``mode`` value configure how CallTest processes a call.\n\ndtmf\n----\n\nThe answering channel sends a random sequence of DTMF tones. The originator\nthen does the same thing. The receivers verify that the codes are correct.\n\nWhen ``dtmf.may_repeat`` is set, the receiver is allowed to read duplicate DTMF\ntones. This flag might be necessary with in-band signalling.\n\n``dtmf.len`` is the number of digits to test. Typically, one digit will be\nrepeated. The sequence is otherwise random.\n\ncall\n----\n\nThe answering channel will acknowledge that it's ringing, but then simply\nhang up.\n\naudio\n-----\n\nTODO.\n\nLike DTMF, but both sides send a sound file instead. The sounds are\nrecorded. They should match, somewhat, but that's not yet tested.\n\nring\n----\n\nOriginate-only: call this number. It should be RINGING. Then hang up.\n\nplay\n----\n\nOriginate-only: call this number. It should answer. Play a sound, then\nhang up.\n\nIf no ``audio.src_out`` sound is specified, simply hang up.\n\nOptionally, ``audio.dst_in`` records incoming audio during the call.\nRecording runs while the outgoing sound is playing.\n\n\nfail\n----\n\nTODO.\n\nOriginate-only: call this number. The call may not go through. It must be\nrejected, some time before ``ringtime``.\n\nAlso TODO: Add a flag to determine whether an intermediate ``Ringing``\nstate is allowed / required / prohibited.\n\n\ntimeout\n-------\n\nTODO.\n\nOriginate-only: call this number. The call may not go through. It must be\nRINGing and then be rejected between ``ringtime`` and ``timeout`` seconds\nlater.\n\n\nwait\n----\n\nAnswer-only: wait for an incoming call, set it to RINGING, wait a few\nseconds, hang up.\n\n\nanswer\n------\n\nAnswer-only: wait for an incoming call, answer it, optionally play a sound,\noptionally\u00b2 record audio while the sound is playing, then hang up.\n\nThe recording will be overlaid with the outgoing sound. This is an Asterisk\nlimitation.\n\n\nrecord\n------\n\nTODO.\n\nAnswer-only: wait for an incoming call, answer it, optionally play a sound,\noptionally record incoming audio until the originator hangs up.\n\n\nNumber format\n+++++++++++++\n\nTODO: currently caller numbers are neither transmitted nor checked.\n\nCallTest recognizes two kinds of phone numbers: site-local extensions, and\neverything else. CallTest distinguishes these by the initial '+'.\n\nOutgoing\n--------\n\nThe outgoing Asterisk channel should be able to handle both kinds directly.\nIf not, either drop-kick your phone provider, or write a \"Local\" channel\nthat mangles the dialled number for you. For instance, if you need to drop\nthe '+', use this macro::\n\n context mangle {\n _+! => { Dial(SIP/broken/${EXTEN:1}) }\n }\n\nand then call ``Local/{nr}@mangle``. As another example, if you need to use\nlcoal number format to dial out::\n\n context mangle {\n _X! => Dial(SIP/broken/${EXTEN}); // pass-thru for local extensions\n _+49123! => Dial(SIP/broken/${EXTEN:6}); // 49123: country+city\n _+49! => Dial(SIP/broken/0${EXTEN:3}); // 49: country\n // _+! => Dial(SIP/broken/00${EXTEN:1});\n _+! => Congestion();\n }\n\nthough you can probably get by with just the first and last line.\n\nThe above works for most of Europe where \"00\" is the international and \"0\"\nthe national prefix. If you're in the NANP (USA or Canada), you probably\nwant to use this macro instead::\n\n context mangle {\n _N! => Dial(SIP/broken/1888${EXTEN}); // 888 is your area code\n _[01]! => Dial(SIP/broken/${EXTEN}); // pass-thru for operator and long-distance\n _+1! => Dial(SIP/broken/${EXTEN:1}); // long distance\n // _+! => Dial(SIP/broken/011${EXTEN:1}); // international\n _+! => Congestion();\n }\n\nThe last line is replaced with a \"Congestion\" blocker so that a mistake\nwon't cause international charges.\n\nIncoming\n--------\n\nCallTest will verify that, the caller's number on an incoming call matches\nthe number in the test's configuration's source link. If that number is\nprefixed with a '+', the incoming number is converted to international\nformat, as per the config file, and needs to match exactly. Otherwise, the\nconfigured number is assumed to be a local extension and must only be at\nthe end of the caller's.\n\nThis ensures that there's no incoming nonsense, while acknowledging that\nsite-local numbers often are not transmitted cleanly.\n\nIf you need Asterisk to mangle the caller's number so that it looks sane\nenough for CallTest, add that to the ``calltest`` macro. For instance, to\ndrop a leading zero (in the NANP it's usually a 9)::\n\n macro calltest(typ) {\n SET(cid=${CALLERID(num)})\n switch(cid) {\n pattern 0.:\n set(CALLERID(num)=${cid:1});\n break;\n default:\n break;\n }\n Stasis(\"calltest\", ${typ});\n Hangup();\n return;\n }\n\nAsterisk configuration\n++++++++++++++++++++++\n\nServer connection\n-----------------\n\nSome parameters in the ``asterisk`` section require further elucidation.\n\n* app: \n\n* audio: the (base of) the \"sound\" URL which Asterisk will use to find your\n test's outgoing sound files. Should be ``sound:/some/absolute/path``.\n\nTest setup\n----------\n\nAsterisk needs to know how to direct incoming calls to the tester. This is\ntypically done with a Stasis macro. This is for ``extensions.ael``::\n\n macro calltest(link,nr) {\n Stasis(calltest,${link},${nr});\n Hangup();\n return;\n }\n\n* calltest: the ``asterisk.app`` config parameter. \n\n* link: the name of the link, in ``asterisk.link``.\n\n* nr: the incoming destination phone number.\n\nYou'd call this macro from your context::\n\n 1234 => &calltest(foo,${EXTEN});\n\nIf you want to route all incoming calls on a channel to this macro, use\nsomething like this context::\n\n context ext_bar {\n s => &calltest(bar,);\n i => &calltest(bar,${INVALID_EXTEN});\n _+! => &calltest(bar,${EXTEN});\n _X! => &calltest(bar,${EXTEN});\n h => Hangup();\n }\n\nWarning::\n\n These calls all have no spaces after the argument-separating commas.\n This is important.\n\nLine setup\n----------\n\nPJSIP is not very forgiving. Sample config: TODO.\n\nIn lieu of voice quality checking, which this system does not yet do, you\nmight want to simply set your endpoints' DTMF mode to \"inband\". Don't use a\ncompressing codec when you do this. You might need to set the test's\n``dtmf_may_repeat`` option. However, in-band DTMF is not particularly\nreliable and may break randomly.\n\nThe random DTMF sequence only uses digits because letters are not\nuniversally passed on, while ``#`` and ``*`` may be interpreted and thus\nswallowed by intermediate systems.\n\nTesting\n-------\n\nThis package contains an ``example.cfg`` configuration. To use it, your\n``asterisk.ael`` file should contain these lines::\n\n macro calltest(link, nr) {\n Stasis(calltest,${link},${nr});\n Hangup();\n return;\n }\n\n context direct {\n _.! => &calltest(${EXTEN},);\n\n answer => {\n Wait(1);\n Answer();\n Wait(5);\n Hangup();\n }\n ringing => {\n Wait(1);\n Ringing();\n Wait(5);\n Hangup();\n }\n progress => {\n Wait(1);\n Progress();\n Wait(5);\n Hangup();\n } \n }\n\nAdd this to your ``ari.conf``:\n\n [example]\n type = user\n password = oh_no_you_do_not\n password_format = plain\n\nFinally, add ``enabled=yes`` to the ``[general]`` section of ``http.conf``.\n\nAfter doing all of this and restarting your Asterisk (reloading \"ael\",\n\"http\" and \"res_ari\" should work too), the command ``./ct -c example.cfg\nrun`` should pass.\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/smurfix/calltest", "keywords": "async", "license": "proprietary", "maintainer": "", "maintainer_email": "", "name": "calltest", "package_url": "https://pypi.org/project/calltest/", "platform": "", "project_url": "https://pypi.org/project/calltest/", "project_urls": { "Homepage": "https://github.com/smurfix/calltest" }, "release_url": "https://pypi.org/project/calltest/0.5.0/", "requires_dist": null, "requires_python": "", "summary": "A distributed phone call test program", "version": "0.5.0" }, "last_serial": 5485583, "releases": { "0.5.0": [ { "comment_text": "", "digests": { "md5": "58ba78a060cb967b3c51059c8b61fa51", "sha256": "1dc7c87cf692c44da52e4032662c35ed297c45267ac20a9c863b931488d44f32" }, "downloads": -1, "filename": "calltest-0.5.0.tar.gz", "has_sig": false, "md5_digest": "58ba78a060cb967b3c51059c8b61fa51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24163, "upload_time": "2019-07-04T08:40:41", "url": "https://files.pythonhosted.org/packages/a7/59/7aa317b94805b992648e8f8be2a5b634d8611e4e820c89e480519e3f8539/calltest-0.5.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "58ba78a060cb967b3c51059c8b61fa51", "sha256": "1dc7c87cf692c44da52e4032662c35ed297c45267ac20a9c863b931488d44f32" }, "downloads": -1, "filename": "calltest-0.5.0.tar.gz", "has_sig": false, "md5_digest": "58ba78a060cb967b3c51059c8b61fa51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24163, "upload_time": "2019-07-04T08:40:41", "url": "https://files.pythonhosted.org/packages/a7/59/7aa317b94805b992648e8f8be2a5b634d8611e4e820c89e480519e3f8539/calltest-0.5.0.tar.gz" } ] }