实现Asterisk外接的管理程序

       Asterisk是一个语音软交换软件,它支持VOIP等协议能够灵活地和手机网、电信固网电话相互对接进行语音交换。Asterisk这个软件的功能也很强大什么多方通话、会议和视频等等都一一集成,除此以为外它还是一个开源的系统,对它有兴趣的朋友不防了解一下。由于项目正在使用它,所以在这里介绍一下如何通过Socket tcpAsterisk进行管理。(对于如何开如AsteriskSocket Tcp管理功能,查看Manager.conf配置文件)。下面通过Smark.Net扩展Manager功能。

       首先我们要对Asterisk Manger Api有个了解,详细查看:

http://www.voip-info.org/wiki/view/Asterisk+manager+API

       协议包的大概格式是:

       Action: <action type><CRLF>
   <Key 1>: <Value 1><CRLF>
   <Key 2>: <Value 2><CRLF>

       每一行分别是以/r/n结束,消息结束符也是/r/n;简单的说只要包的某段内容是/r/n/r/n就表明该消息结束。根据这情况我实现一个分包功能:

       public class DataAnalyes:Smark.Net.IDataAnalyse

    {

        #region IDataAnalyse 成员

 

        public bool  Eof(byte[] data,int index,int count,Smark.Net.IClient client)

        {

            if (index >= 3)

            {

                if (data[index] == 10 && data[index - 1] == 13 && data[index - 2] == 10 && data[index - 3] == 13)

                {

                    return true;

                }

            }

            return false;

        }

        #endregion

    }

       为了把Client区分开来,所以也实现一个ManagerClient:

    public class ManagerClient:Smark.Net.Client<DataAnalyes>

    {

        public ManagerClient(System.Net.Sockets.Socket socket) : base(socket) { }

}

Socket tcp连接处理核心就扩展完成,下面就是对指令消息的封装。首先封装一个指令的基础类:

    public abstract  class APIBase:Smark.Net.IMessage

    {

        public APIBase()

        {

            ActionID = Guid.NewGuid().ToString("N");

        }

      

        public string ActionID

        {

            get;

            set;

        }

        public virtual byte[] SaveData(Encoding coding)

        {

            StringBuilder sb = new StringBuilder();

            sb.Append("Action: " + GetType().Name);

            sb.Append("\r\n");

            List<PropertyAttribute> properies = new List<PropertyAttribute>();

            foreach (PropertyInfo pi in GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))

            {

                PropertyAttribute[] pa = (PropertyAttribute[])pi.GetCustomAttributes(typeof(PropertyAttribute), false);

                if (pa.Length > 0)

                {

                    pa[0].Handler = pi;

                    properies.Add(pa[0]);

                }

            }

            properies.Sort();

            //根据每个属性值合拼参数值

            foreach (PropertyAttribute p in properies)

            {

            

                sb.Append((p.Name==null?p.Handler.Name:p.Name) + ": " + p.Handler.GetValue(this, null));

                sb.Append("\r\n");

            }

            sb.Append("ActionID: " + ActionID);

            sb.Append("\r\n");

            sb.Append("\r\n");

            return coding.GetBytes(sb.ToString());

        }

        public void LoadData(byte[] data, Encoding coding)

        {

            throw new NotImplementedException();

        }

        public void Send(Smark.Net.IClient Client)

        {

            Client.Send(this);

        }

    }

       实现Login命令

       public class Login : APIBase

    {

       

        [PropertyAttribute(0)]

        public string Username

        {

            get;

            set;

        }

        [PropertyAttribute(1)]

        public string Secret

        {

            get;

            set;

        }

    }

实现Asterisk ManagerCOMMAND命令。

    public class Command : APIBase

    {

        [PropertyAttribute(0)]

        public string command

        {

            get;

            set;

        }

    }

       到这里一个简单的基于Command指令的管理就完成,看上去是不是很简单。

       接下来看下这东西到底可不可行了:)连接到Asterisk登陆一下看。

            ManagerClient mc = Server<ManagerClient>.CreateClient("192.168.1.149", 5038);

            mc.DataReceive += (o, e) => {

                Console.WriteLine(Encoding.ASCII.GetString(e.Data));

            };

            mc.Receive();

            Login login = new Login();

            login.Username = "test";

            login.Secret = "123456";

            login.Send(mc);

      

:)提示登陆成功了。接下来执行一个Command指命.

            Command cmd = new Command();

            cmd.command = "core show applications";

            cmd.Send(mc);


完整代码可以到Smark Google Code下载。

 

posted on 2009-08-19 14:10  henry  阅读(2723)  评论(7)    收藏  举报

导航