Asterisk module dev: Difference between revisions

From 탱이의 잡동사니
Jump to navigation Jump to search
 
(8 intermediate revisions by the same user not shown)
Line 22: Line 22:
</pre>
</pre>


== Core file ==
== Debug ==
=== Backtrace ===
* https://wiki.asterisk.org/wiki/display/AST/Getting+a+Backtrace#GettingaBacktrace-GettingInformationForADeadlock
 
=== Core file ===
보통 Asterisk 를 컴파일을 하면 코어파일이 생기지 않는다.
보통 Asterisk 를 컴파일을 하면 코어파일이 생기지 않는다.


Line 33: Line 37:
더 자세한 디버깅 옵션을 확인하고 싶다면 이곳<ref>http://www.voip-info.org/wiki/view/Asterisk+debugging</ref>을 참조하자.
더 자세한 디버깅 옵션을 확인하고 싶다면 이곳<ref>http://www.voip-info.org/wiki/view/Asterisk+debugging</ref>을 참조하자.


=== Backtracing ===
Backtracing a core dump file in /tmp
Backtracing a core dump file in /tmp
<pre>
<pre>
start Asterisk with safe_asterisk
start Asterisk with safe_asterisk
Line 40: Line 43:
enter "bt" while in gdb (or do a "bt full")
enter "bt" while in gdb (or do a "bt full")
enter "thread apply all bt"
enter "thread apply all bt"
</pre>
=== ast_coredumper ===
Asterisk version 13.14.0 and 14.3.0 added a few tools to make debugging easier.
<pre>
$ sudo /var/lib/asterisk/scripts/ast_coredumper --help
NAME
ast_coredumper - Dump and/or format asterisk coredump files
SYNOPSIS
ast_coredumper [ --help ] [ --running | --RUNNING ] [ --latest ]
[ --tarball-coredumps ] [ --delete-coredumps-after ]
[ --tarball-results ] [ --delete-results-after ]
[ --tarball-config ] [ --tarball-uniqueid="<uniqueid>" ]
[ --no-default-search ] [ --append-coredumps ]
[ --asterisk-bin="path" ]
[ <coredump> | <pattern> ... ]
</pre>
=== Getting information for a Deadlock ===
When you suspect asterisk is deadlocked, you can use ast_coredumper to dump the currently running asterisk instance.
주의!!!! 이 작업은 현재 작동중인 Asterisk 프로세스의 코어덤프를 뜨는 작업이다. 작업을 진행시, 작업이 진행되는 동안 Asterisk 는 call handle 작업을 멈추게 된다.
그리고 동작중인 프로세스의 메모리 사이즈와 동일한 크기의 덤프파일을 만들고 추가적인 분석 파일도 생성하므로, 작업시 디스크 용량에도 신경을 써야 한다.
<pre>
$ sudo /var/lib/asterisk/scripts/ast_coredumper --running
Found a single asterisk instance running as process 25245
WARNING:  Taking a core dump of the running asterisk instance will suspend call processing while the dump is saved.  Do you wish to continue? (y/N) y
Dumping running asterisk process to /tmp/core-asterisk-running-2019-06-05T07-22-42+0000
Processing /tmp/core-asterisk-running-2019-06-05T07-22-42+0000
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-thread1.txt
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-brief.txt
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-full.txt
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-locks.txt
</pre>
</pre>


Line 79: Line 117:
ASTERISK_REGISTER_FILE()
ASTERISK_REGISTER_FILE()
</pre>
</pre>
== How to extend SIP functionality in Asterisk ==
=== A brief note on design philosophy ===
One of the driving reasons for rewriting SIP was that chan_sip was monolithic. In other words, all of the functionality was crammed together within a single file, with application and underlying transaction, transport, and other SIP-related maintenance being intermixed. The new SIP work is modeled very differently. The SIP functionality is built on top of the PJSIP stack so that the majority of protocol-related logic is taken care of for us and we don't need to concern ourselves with it when writing application-level code. In addition, the approach of writing new code is more modular than it was in the past. Typically, a single module deals with one application-level aspect and nothing else. If you look inside the Asterisk source code in the res/ directory, you will find many files that begin with the prefix res_sip*. Each of these is a separate module that is responsible for some small portion of functionality.
When making additions to the SIP code in Asterisk, it strongly recommended that you write your new functionality in its own module. Unless you are making improvements to functionality that already exists in another module, you will likely want to keep your new logic completely separate from the rest of the SIP processing. This affords several benefits:
* It is easy to port your code to a new version of Asterisk when you decide to upgrade. Rather than worrying about whether your patch will apply cleanly in the new version of Asterisk, you can simply plug your module in and things should just work.
* It allows an easy method for people to enable or disable your functionality. Most SIP features are not essential to the core workings of Asterisk, so allowing your functionality to be optionally loaded will make people happy.
* It enforces discipline in your coding. If you keep the mindset that you have your own area you can mess with and not to try to change things outside that area, then you are less likely to muddy the core of SIP in Asterisk.
=== SIP session supplement ===
The most common SIP use in Asterisk is the setting up of media sessions via a dialog initiated by an INVITE request. Asterisk has taken the shortcut of referring to such a dialog and its associated media session as a "session". Sessions in Asterisk are made extendable via a mechanism called "Session supplements". Session supplements are a set of callbacks that are called at various points throughout the lifetime of a session. The callbacks provided allow for your supplement to be visited when the session begins and ends, as well as when any SIP request or response is ent or received during the session. Session supplements are have datastores, similar to what channel have, so your supplement can store arbitrary data on a session and ertrieve or remove it when necessary. Session supplements can be tuned to only be called for specific SIP methods as well. Some potential examples of when you might use SIP session supplements are:
* You wish to store some sort of information on a channel or other central Asterisk structure based on the value of a SIP header in a request or response.
* You wish to add headers to an outbound SIP request or response based on saved data in your module.
* You wish to send a specific error response to an inbound request based on a SIP header or system state.
* You wish to add support for some specific type of in-dialog request(such as a specific INFO package)
아래의 예제를 참조하면 된다.
* res/res_sip_rfc3326.c
* res/res_sip_callerid.c
각각의 메시지와 상황에 맞게 작동하도록 할 수 있다.
* outgoing_response: The specified callback is called when an outgoing SIP response is sent on the session.
* incoming_request : The specified callback is called when an incoming SIP request arrives on the session.
* incoming_response: The specified callback is called when an incoming SIP response arrives on the session.
* priority: This is mostly applicable to session supplements that wish to act on the initial incoming INVITE a session. This will help determine when the supplements are called. Supplements with lower numbered priority are called before those with higher numbers. The most common use for this is to ensure that the supplement is called either before or after the ast_channel associated with the session is created.


== See also ==
== See also ==
Line 85: Line 150:
* http://blog.russellbryant.net/2008/06/19/how-to-write-an-asterisk-module-part-1/ - How-to: Write an Asterisk Module, Part 1
* http://blog.russellbryant.net/2008/06/19/how-to-write-an-asterisk-module-part-1/ - How-to: Write an Asterisk Module, Part 1
* http://matthewjordan.net/2014/07/29/writing-an-asterisk-module/ - Writing an Asterisk Module
* http://matthewjordan.net/2014/07/29/writing-an-asterisk-module/ - Writing an Asterisk Module
* https://wiki.asterisk.org/wiki/display/AST/How+to+extend+SIP+functionality+in+Asterisk#HowtoextendSIPfunctionalityinAsterisk-SIPsessionsupplement - How to extend SIP functionality in Asterisk


== References ==
== References ==

Latest revision as of 11:00, 5 June 2019

Ovreview

Asterisk module 만들어보기

Valgrind test

정확한 내용은 이곳<ref>https://wiki.asterisk.org/wiki/display/AST/Valgrind</ref>에서 확인할 수 있다.

Valgrind test 를 하기 위해서는 먼저 Asterisk 를 최적화 옵션을 끈채로 소스 컴파일을 하고, 이후 supp 파일과 함께 valgrind 를 실행하면 된다.

    Run 'make menuselect' and in the Compiler Options, enable DONT_OPTIMIZE. A bug marshal may also ask you to enable additional compiler flags depending upon the nature of the issue.
    Rebuild and install Asterisk.

    Run Asterisk as follows, where /usr/src/asterisk/ is location of asterisk source code.
    valgrind --suppressions=/usr/src/asterisk/contrib/valgrind.supp --log-fd=9 asterisk -vvvvcg 9>valgrind.txt
    Reproduce the issue. Following the manifestation of the issue (or when the process crashes), upload the valgrind.txt to the issue tracker.

최적화 옵션 On/Off 설정은 Compiler Flags 항목에 있다.

    --- Core ---
[*] DONT_OPTIMIZE
...

Debug

Backtrace

Core file

보통 Asterisk 를 컴파일을 하면 코어파일이 생기지 않는다.

코어파일이 남지 않으면 디버깅이 힘들어진다. 다음의 작업을 해주자.<ref>http://stackoverflow.com/questions/20743376/asterisk-gdb-how-to-debug-crash-with-gdb-and-asterisk-11-5-1-but-still-core-dunp</ref>

1) compile asterisk with debug symbols

2) in /etc/asterisk/asterisk.conf enable core dump.

더 자세한 디버깅 옵션을 확인하고 싶다면 이곳<ref>http://www.voip-info.org/wiki/view/Asterisk+debugging</ref>을 참조하자.

Backtracing a core dump file in /tmp
start Asterisk with safe_asterisk
enter "gdb asterisk core.xxxx"
enter "bt" while in gdb (or do a "bt full")
enter "thread apply all bt"

ast_coredumper

Asterisk version 13.14.0 and 14.3.0 added a few tools to make debugging easier.

$ sudo /var/lib/asterisk/scripts/ast_coredumper --help
NAME
	ast_coredumper - Dump and/or format asterisk coredump files

SYNOPSIS
	ast_coredumper [ --help ] [ --running | --RUNNING ] [ --latest ]
		[ --tarball-coredumps ] [ --delete-coredumps-after ]
		[ --tarball-results ] [ --delete-results-after ]
		[ --tarball-config ] [ --tarball-uniqueid="<uniqueid>" ]
		[ --no-default-search ] [ --append-coredumps ]
		[ --asterisk-bin="path" ]
		[ <coredump> | <pattern> ... ]

Getting information for a Deadlock

When you suspect asterisk is deadlocked, you can use ast_coredumper to dump the currently running asterisk instance.

주의!!!! 이 작업은 현재 작동중인 Asterisk 프로세스의 코어덤프를 뜨는 작업이다. 작업을 진행시, 작업이 진행되는 동안 Asterisk 는 call handle 작업을 멈추게 된다. 그리고 동작중인 프로세스의 메모리 사이즈와 동일한 크기의 덤프파일을 만들고 추가적인 분석 파일도 생성하므로, 작업시 디스크 용량에도 신경을 써야 한다.

$ sudo /var/lib/asterisk/scripts/ast_coredumper --running
Found a single asterisk instance running as process 25245
WARNING:  Taking a core dump of the running asterisk instance will suspend call processing while the dump is saved.  Do you wish to continue? (y/N) y
Dumping running asterisk process to /tmp/core-asterisk-running-2019-06-05T07-22-42+0000
Processing /tmp/core-asterisk-running-2019-06-05T07-22-42+0000
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-thread1.txt
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-brief.txt
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-full.txt
Creating /tmp/core-asterisk-running-2019-06-05T07-22-42+0000-locks.txt

TEST_FRAMEWORK

Asterisk 에서 제공하는 TEST 소스 파일들을 컴파일하고 테스트하기 위해서는 TEST_FRAMEWORK 를 활성화 시켜야 한다. TEST_FRAMEWORK 를 활성화시키지 않으면 다음과 memuselect 에서 다음과 같은 메시지가 나온다.

XXX test_pbx
XXX test_poll
... More ...

ACL test module
Depends on: TEST_FRAMEWORK(E)

TEST_FRAMEWORK 활성화는 ./configure 실행시, --enable-dev-mode 옵션과 함께 실행하면 활성화 된다.

$ ./configure --enable-dev-mode

14.1.1

Asterisk 14.1.1 부터는 꽤나 많은 것들이 바꼈다.

AST_MODULE_SELF_SYM

14.1.1 부터는 AST_MODULE_SELF_SYM 을 define 해주어야 한다.

CFLAGS+=-DAST_MODULE=\"your_module_name\" -DAST_MODULE_SELF_SYM=__internal_your_module_name_self

ASTERISK_REGISTER_FILE

ASTERISK_FILE_VERSION(__FILE__, "$Revision$")

14.1.1 부터는 아래의 함수를 사용하거나 그냥 삭제 하도록 하자. 15부터는 사용하지 않는다고 한다.

(11:11:57 PM) coreyfarrell: pchero: I suggest just removing ASTERISK_FILE_VERSION / ASTERISK_REGISTER_FILE.  it no longer does anything and will not exist in Asterisk 15.
ASTERISK_REGISTER_FILE()

How to extend SIP functionality in Asterisk

A brief note on design philosophy

One of the driving reasons for rewriting SIP was that chan_sip was monolithic. In other words, all of the functionality was crammed together within a single file, with application and underlying transaction, transport, and other SIP-related maintenance being intermixed. The new SIP work is modeled very differently. The SIP functionality is built on top of the PJSIP stack so that the majority of protocol-related logic is taken care of for us and we don't need to concern ourselves with it when writing application-level code. In addition, the approach of writing new code is more modular than it was in the past. Typically, a single module deals with one application-level aspect and nothing else. If you look inside the Asterisk source code in the res/ directory, you will find many files that begin with the prefix res_sip*. Each of these is a separate module that is responsible for some small portion of functionality.

When making additions to the SIP code in Asterisk, it strongly recommended that you write your new functionality in its own module. Unless you are making improvements to functionality that already exists in another module, you will likely want to keep your new logic completely separate from the rest of the SIP processing. This affords several benefits:

  • It is easy to port your code to a new version of Asterisk when you decide to upgrade. Rather than worrying about whether your patch will apply cleanly in the new version of Asterisk, you can simply plug your module in and things should just work.
  • It allows an easy method for people to enable or disable your functionality. Most SIP features are not essential to the core workings of Asterisk, so allowing your functionality to be optionally loaded will make people happy.
  • It enforces discipline in your coding. If you keep the mindset that you have your own area you can mess with and not to try to change things outside that area, then you are less likely to muddy the core of SIP in Asterisk.

SIP session supplement

The most common SIP use in Asterisk is the setting up of media sessions via a dialog initiated by an INVITE request. Asterisk has taken the shortcut of referring to such a dialog and its associated media session as a "session". Sessions in Asterisk are made extendable via a mechanism called "Session supplements". Session supplements are a set of callbacks that are called at various points throughout the lifetime of a session. The callbacks provided allow for your supplement to be visited when the session begins and ends, as well as when any SIP request or response is ent or received during the session. Session supplements are have datastores, similar to what channel have, so your supplement can store arbitrary data on a session and ertrieve or remove it when necessary. Session supplements can be tuned to only be called for specific SIP methods as well. Some potential examples of when you might use SIP session supplements are:

  • You wish to store some sort of information on a channel or other central Asterisk structure based on the value of a SIP header in a request or response.
  • You wish to add headers to an outbound SIP request or response based on saved data in your module.
  • You wish to send a specific error response to an inbound request based on a SIP header or system state.
  • You wish to add support for some specific type of in-dialog request(such as a specific INFO package)

아래의 예제를 참조하면 된다.

  • res/res_sip_rfc3326.c
  • res/res_sip_callerid.c

각각의 메시지와 상황에 맞게 작동하도록 할 수 있다.

  • outgoing_response: The specified callback is called when an outgoing SIP response is sent on the session.
  • incoming_request : The specified callback is called when an incoming SIP request arrives on the session.
  • incoming_response: The specified callback is called when an incoming SIP response arrives on the session.
  • priority: This is mostly applicable to session supplements that wish to act on the initial incoming INVITE a session. This will help determine when the supplements are called. Supplements with lower numbered priority are called before those with higher numbers. The most common use for this is to ensure that the supplement is called either before or after the ast_channel associated with the session is created.

See also

References

<references />