Slimming Asterisk for the NSLU2 under Debian

本文介绍如何将Asterisk PBX系统精简至仅使用六个模块运行,并详细记录了适用于Linksys NSLU2设备的配置步骤。文章涵盖SIP电话、ITSP接入及回声测试等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A FULLY WORKING ASTERISK SIP PBX RUNNING WITH ONLY 6 MODULES LOADED ! READ ON…

This howto is based on Asterisk 1.2 under Debian Etch. Please let me know through the comments if it works for you under other versions (and if it doesn’t, please provide the steps to get a working system). Thanks.

My needs :

I had to slim Asterisk down to the most minimalistic configuration possible to run on my Linksys NSLU2 (ARM cpu @ 266 Mhz, RAM 32 MB).

- SIP calls between my IP phones and softphone
- Incoming/Outgoing calls through a SIP ITSP (ipness.com)
- Echo test to make sure audio is going through in some situation
- I only use the alaw codec, compatible with my IP phones and ITSP, you should avoid transcoding. My DSL connection offers dynamic IP only and gives around 3400 Kbps down/386 Kbps up. I could use the GSM codec, but the ITSP doesn’t support it
- No voicemail or other apps

My setup :

- The NSLU2 is behind a NAT router
- Home phone on the same subnet as the NSLU2
- Work phone behind NAT
- Softphone used from several places

Router configuration :

- Forward port UDP/5060 to UDP/5070 to the NSLU2
- UDP/5060 is used for SIP traffic (signalling)
- UDP/5061 to UDP/5070 is used for RTP traffic (audio)

Asterisk configuration files :

Before diving into the configuration..
IMPORTANT !!!
If you want to comment something out in the configuration you’ll start the line with a semi-colon (“;”)
# is used for file inclusions. # IS NOT USED FOR COMMENTS !!!

I moved unnecessary files under backup/

root@nslu2:/etc/asterisk# ls -l
total 40
-rw-r--r-- 1 root root 247 2008-04-13 22:03 asterisk.conf
drwxr-xr-x 2 root root 4096 2008-04-13 22:03 backup
-rw-r--r-- 1 root root 141 2008-04-13 22:10 extensions.conf
-rw-r--r-- 1 root root 1660 2008-04-13 23:34 features.conf
-rw-r--r-- 1 root root 2158 2008-04-13 22:03 logger.conf
-rw-r--r-- 1 root root 438 2008-04-13 23:37 modules.conf
-rw-r--r-- 1 root root 395 2008-04-13 22:03 rtp.conf
-rw-r--r-- 1 root root 299 2008-04-13 22:04 sip.conf
-rw-r--r-- 1 root root 904 2008-04-13 23:40 custom_extensions.conf
-rw-r--r-- 1 root root 1349 2008-04-14 09:31 custom_sip.conf

/etc/asterisk/extensions.conf :

[general]

static=yes
writeprotect=no
autofallthrough=yes
clearglobalvars=no
priorityjumping=no

; let's include custom_extensions.conf into extensions.conf
#include "/etc/asterisk/custom_extensions.conf"

/etc/asterisk/features.conf : default configuration

/etc/asterisk/logger.conf : default configuration

/etc/asterisk/modules.conf :

Order in which modules are loaded can be important. E.g. : res_features.so must be loaded before chan_sip.so

[modules]
autoload=no             ; only load explicitely declared modules

load => app_echo.so     ; echo application
load => codec_alaw.so   ; alaw codec for voice
load => pbx_config.so   ; reading and loading configuration
load => res_features.so ; chan_sip.so dependency
load => chan_sip.so     ; SIP protocol
load => app_dial.so     ; Dial application

[global]

/etc/asterisk/rtp.conf :

The audio is going through these UDP ports, they must be forwarded to the server in the router.

In this example, the number of ports used by Asterisk is relatively low (I never have more than one call going through the PBX). Set as much as you need, a channel may need up to 2 ports. Also only even ports are actually used.

[general]
rtpstart=5061
rtpend=5070

/etc/asterisk/sip.conf :

Having a dynamic IP, I must use externhost with a fresh rate of 60 seconds for resolving the domain.
If you have a static IP, define it in externip=

Localnet must be defined with your network subnet(s), localnet subnets are never passed in the “Via” parameter (can be seen in sip traces).

realm must be a unique ID

The “register =>” line is necessary in order to receive incoming calls from the ITSP.

[general]

context=incoming
bindport=5060
bindaddr=0.0.0.0

srvlookup=yes

externhost=mydynamichostname.dyndns.org
externrefresh=60

localnet=192.168.1.0/255.255.255.0

realm=mydynamichostname.dyndns.org

register => 3221234567:password:login@ipness.net:6060/3221234567

#include "/etc/asterisk/custom_sip.conf"

/etc/asterisk/custom_extensions.conf :

custom_extensions.conf is my customized dialplan

- Home phone and softphone can call local phones (1XXX range)
- Home phone and softphone can call national (e.g. : 02 123 45 67) and international numbers (00 1 910 123 4567) through the ITSP
- Work phone can only call local phones
- Every phone can call the echo application
- Incoming calls make 1001 ring first, then 1002 and finally 1000 (each with a timeout of 30 seconds)

[globals]

;;; apps context

[apps]
exten => 444,1,Answer()
exten => 444,n,Wait(1)
exten => 444,n,Echo

;;; incoming calls context

[incoming]
exten => 3221234567,1,Dial(SIP/1001,30)
exten => 3221234567,n,Dial(SIP/1002,30)
exten => 3221234567,n,Dial(SIP/1000,30)

;;; outgoing calls context

; local calls only
[local]
include => apps

exten => _1XXX,1,Dial(SIP/${EXTEN})
exten => _1XXX,n,NoOp(===== DIAL STATUS --> ${DIALSTATUS} =====)
exten => _1XXX,n,Hangup()

; national (Belgium, code 32) calls only
[national]
include => local
include => apps

exten => _0N.,1,Dial(SIP/0032${EXTEN:1}@itsp_ipness)
exten => _0N.,n,NoOp(===== DIAL STATUS --> ${DIALSTATUS} =====)
exten => _0N.,n,Hangup()

; international calls
[international]
include => national
include => local
include => apps

exten => _00.,1,Dial(SIP/${EXTEN}@itsp_ipness)
exten => _00.,n,NoOp(===== DIAL STATUS --> ${DIALSTATUS} =====)
exten => _00.,n,Hangup()

/etc/asterisk/custom_sip.conf :

custom_sip.conf is my customized accounts file.

canreinvite must be set to no for all sip accounts (unless you have several phones on the server subnet, than you can set to yes).
NAT must be set to yes for any device behind NAT routers.

; SIP accounts

[1000]
type=friend
context=international
callerid="Softphone" <1000>
qualify=yes
secret=1111
nat=yes
canreinvite=no
dtmfmode=rfc2833
host=dynamic
call-limit=2
disallow=all
allow=alaw

[1001]
type=friend
context=international
callerid="Home" <1001>
qualify=yes
secret=1111
nat=no ; IP phone is on the same subnet as the server
canreinvite=no
dtmfmode=rfc2833
host=dynamic
call-limit=2
disallow=all
allow=alaw

[1002]
type=friend
context=local
callerid="Work" <1002>
qualify=yes
secret=1111
nat=yes
canreinvite=no
dtmfmode=rfc2833
host=dynamic
call-limit=2
disallow=all
allow=alaw

[1003]
type=friend
context=local
callerid="Friend" <1003>
qualify=no
secret=1111
nat=yes
canreinvite=no
dtmfmode=rfc2833
host=dynamic
call-limit=1
disallow=all
allow=alaw

; ITSP

[itsp_ipness]
type=peer
username=login
secret=password
fromuser=3221234567
fromdomain=ipness.net
host=ipness.net
port=6060
nat=yes
canreinvite=no
context=incoming
insecure=very
qualify=yes
disallow=all
allow=alaw

Result :

nslu2*CLI> show modules
Module                         Description                              Use Count
app_echo.so                    Simple Echo Application                  0
codec_alaw.so                  A-law Coder/Decoder                      0
pbx_config.so                  Text Extension Configuration             0
res_features.so                Call Features Resource                   1
chan_sip.so                    Session Initiation Protocol (SIP)        0
app_dial.so                    Dialing Application                      0       

nslu2*CLI> show applications
    -= Registered Asterisk Applications =-
       AbsoluteTimeout: Set absolute maximum time of call
                Answer: Answer a channel if ringing
            BackGround: Play a file while awaiting extension
                  Busy: Indicate the Busy condition
            Congestion: Indicate the Congestion condition
                  Dial: Place a call and connect to the current channel
          DigitTimeout: Set maximum timeout between digits
                  Echo: Echo audio read back to the user
            ExecIfTime: Conditional application execution based on the current time
                  Goto: Jump to a particular priority, extension, or context
                GotoIf: Conditional goto
            GotoIfTime: Conditional Goto based on the current time
                Hangup: Hang up the calling channel
             ImportVar: Import a variable from a channel into a new variable
                  NoOp: Do Nothing
                  Park: Park yourself
            ParkedCall: Answer a parked call
              Progress: Indicate progress
              ResetCDR: Resets the Call Data Record
       ResponseTimeout: Set maximum timeout awaiting response
             RetryDial: Place a call, retrying on failure allowing optional exit extension.
               Ringing: Indicate ringing tone
              SayAlpha: Say Alpha
             SayDigits: Say Digits
             SayNumber: Say Number
           SayPhonetic: Say Phonetic
                   Set: Set channel variable(s) or function value(s)
           SetAccount: Set the CDR Account Code
           SetAMAFlags: Set the AMA Flags
          SetGlobalVar: Set a global variable to a given value
           SetLanguage: Set the channel's preferred language
                SetVar: Set channel variable(s)
          SIPAddHeader: Add a SIP header to the outbound call
           SIPDtmfMode: Change the dtmfmode for a SIP call
          SIPGetHeader: Get a SIP header from an incoming call
                  Wait: Waits for some time
             WaitExten: Waits for an extension to be entered
    -= 37 Applications Registered =-

nslu2*CLI> show functions
Installed Custom Functions:
--------------------------------------------------------------------------------
CHECKSIPDOMAIN        CHECKSIPDOMAIN(<domain|IP>)          Checks if domain is a local domain
SIPCHANINFO           SIPCHANINFO(item)                    Gets the specified SIP parameter from the current channel
SIPPEER               SIPPEER(<peername>[:item])           Gets SIP peer information
SIP_HEADER            SIP_HEADER(<name>)                   Gets the specified SIP header
4 custom functions installed.

Asterisk is using around 12 MB of memory when idle.

### Slimming 剪枝方法概述 Slimming 是一种基于通道剪枝的方法,其核心思想是通过引入 BN 层中的缩放因子来决定哪些通道可以被移除。具体来说,在训练过程中加入 L1 正则化项以稀疏化这些缩放因子,从而使得不重要的通道对应的缩放因子接近于零[^1]。 #### 实现过程详解 以下是 Slimming 的主要实现步骤: 1. **L1 正则化的应用** 在 Batch Normalization (BN) 层中,每个通道都有一个可学习的参数 γ(即缩放因子)。通过对 γ 应用 L1 正则化,可以使部分通道的重要性下降到几乎为零的程度。这一步骤可以通过修改损失函数完成: \[ Loss_{total} = Loss_{original} + \lambda \sum |\gamma_i| \] 这里的 λ 控制正则化的强度,γ 表示 BN 层的缩放因子[^3]。 2. **重要性评估与剪枝决策** 训练完成后,根据各通道对应 γ 的绝对值大小对其进行排序,并按照预设的比例去除那些 γ 较小的通道及其关联的权重矩阵。这一过程能够显著减小模型规模并提升推理速度。 3. **微调优化性能** 完成剪枝之后,为了恢复因结构简化而可能丢失的部分精度,通常会对剩余网络重新进行一轮短时间的微调操作[^2]。 #### Python 示例代码 下面提供了一个简单的 PyTorch 版本实现框架供参考: ```python import torch.nn as nn import torch.optim as optim class SlimmableModel(nn.Module): def __init__(self, num_classes=10): super(SlimmableModel, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1) self.bn1 = nn.BatchNorm2d(64) def forward(self, x): out = self.conv1(x) out = self.bn1(out) return out def apply_l1_regularization(model, lambda_reg): l1_loss = 0 for module in model.modules(): if isinstance(module, nn.BatchNorm2d): # 对所有BatchNorm层施加惩罚 gamma_abs_sum = torch.sum(torch.abs(module.weight)) l1_loss += gamma_abs_sum return lambda_reg * l1_loss model = SlimmableModel() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.01) for data, target in dataloader: optimizer.zero_grad() output = model(data) loss = criterion(output, target) + apply_l1_regularization(model, lambda_reg=0.0001) loss.backward() optimizer.step() # 后续执行剪枝逻辑... ``` 上述代码展示了如何向标准训练流程中融入 L1 正则化机制以便后续实施剪枝处理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值