- asternet download site :
https://github.com/AsterNET/AsterNET/
- asterisk server side config (manager.conf)
1 2 3 4 5 6 7 8 9 10 11 12 |
[general] enabled = yes port = 5038 bindaddr = 0.0.0.0 [mark] secret = 12345678 deny=0.0.0.0/0.0.0.0 permit=103.244.191.246/255.255.255.0 read = call write = all |
deny + permit mean only allow 103.244.191.246 this IP visit
read = call mean afer connect AMI and asterisk , asterisk only send call event to AMI ,this can avoid too many event been sent to AMI , since AMI is UDP connection .
- modify of asternet program :
a) in
1 |
btnConnect_Click |
after
1 |
manager = new ManagerConnection(address, port, user, password); |
add
1 2 3 |
manager.DialBegin += manager_DialBegin; // this also can be omit manager.DialEnd += manager_DialEnd; manager.Hangup += call_hangup_Events; |
their cresponding function is :
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
void manager_DialEnd(object sender, DialEndEvent e) { DateTime dtAnswerTime = e.DateReceived; string sUnique = e.DestUniqueId; this.Invoke((MethodInvoker)delegate { while (true) { for (int i = 0; i < this.dataGridView1.Rows.Count; i++) { if (this.dataGridView1.Rows[i].Cells["uniqueID"].Value.ToString() == sUnique) { this.dataGridView1.Rows[i].Cells["B answer time"].Value = dtAnswerTime; return; } } } //listBox1.Items.Add(sUnique); }); return; } void manager_DialBegin(object sender, DialBeginEvent e) { string srtAnumber = e.Attributes["destcalleridnum"].ToString(); string strBnumber = e.DialString; DateTime dtRingTime = e.DateReceived; string sUnique = e.DestUniqueId; this.Invoke((MethodInvoker)delegate { int index = this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[index].Cells["A number"].Value = srtAnumber; this.dataGridView1.Rows[index].Cells["B number"].Value = strBnumber; this.dataGridView1.Rows[index].Cells["B ring time"].Value = dtRingTime; this.dataGridView1.Rows[index].Cells["uniqueID"].Value = sUnique; this.dataGridView1.Rows[index].HeaderCell.Value = String.Format("{0}", index + 1); //this.dataGridView1.Refresh(); }); return; } void call_hangup_Events(object sender, HangupEvent e) { //string sUnique = e.UniqueId; //DateTime dtAnswerTime = e.DateReceived; //this.Invoke((MethodInvoker)delegate //{ // for (int i = 0; i < this.dataGridView1.Rows.Count; i++) // { // if (this.dataGridView1.Rows[i].Cells["uniqueID"].Value.ToString() == sUnique) // { // this.dataGridView1.Rows[i].Cells["B hangup time"].Value = dtAnswerTime; // } // } //}); //return; DateTime dtAnswerTime = e.DateReceived; string sUnique = e.Attributes["linkedid"].ToString(); this.Invoke((MethodInvoker)delegate { while (true) { for (int i = 0; i < this.dataGridView1.Rows.Count; i++) { if (this.dataGridView1.Rows[i].Cells["uniqueID"].Value.ToString() == sUnique) { this.dataGridView1.Rows[i].Cells["B hangup time"].Value = dtAnswerTime; return; } } } //listBox1.Items.Add(sUnique); }); return; } |
above code will let AMI recv call event include : dialbegin , dialend , and hangup , then write these info in datagridview
add a button , in its click event , write :
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 |
long initBNumber = 70019779805550000; //long initBNumber = 80019779805550000; long initANumber = 97477009999; for (int i = 0; i < 100; i++) { OriginateAction oc = new OriginateAction(); oc.Async = true; oc.Context = @"autodialer"; oc.Priority = "1"; //oc.Channel = @"sip/ast2/70019779805550000"; oc.Channel = @"sip/ast2/" + (initBNumber+i).ToString(); //oc.CallerId = "97477009999"; oc.CallerId = (initANumber+i).ToString(); oc.Exten = "100"; oc.Timeout = ORIGINATE_TIMEOUT; manager.SendAction(oc, null); } |
this will generate 100 calls to asterisk , especially notice :
1 |
<span style="color: #ff6600;">oc.Async = true;</span> |
without this property , calls will not success . this answer come from my ask queston in :
https://github.com/AsterNET/AsterNET/issues/146
- here is full code AsterNET , pls check winform project .
2018-6-1 modify
上述方法是把 cdr 写到 datagridview 里, 但是,当cdr非常多的时候就不适合, 因此, 换一种方法, 只记录打通的电话次数和total duration , 实现如下:
在 form 类定义
1 2 3 4 5 6 7 8 |
class CDR { public string Anumber; public string Bnumber; public DateTime answerTime; public DateTime hangupDate; } |
1 |
Dictionary<string, CDR> dcdr = new Dictionary<string, CDR>(); |
in some buttone ‘s click event , add :
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 |
dcdr.Clear(); // asterisk 190 N calls long initBNumber = 500036312340000; long initANumber = 85222930000; int j = int.Parse(textBox1.Text); for (int i = 0; i < j; i++) { OriginateAction oc = new OriginateAction(); oc.Async = true; oc.Context = @"autodialer"; oc.Priority = "1"; oc.Channel = @"sip/astToTB/" + (initBNumber + i).ToString(); oc.CallerId = (initANumber + i).ToString(); oc.Exten = "100"; oc.Timeout = ORIGINATE_TIMEOUT; CDR call = new CDR(); call.Anumber = oc.CallerId; call.Bnumber = (initBNumber + i).ToString(); try { dcdr.Add(call.Anumber, call); manager.SendAction(oc, null); } catch (Exception ep) { } } |
in manager_DialEnd function , add
1 2 3 4 5 6 7 8 9 |
DateTime dtAnswerTime = e.DateReceived; string Srcnumber = e.Attributes["destcalleridnum"]; if (dcdr.ContainsKey(Srcnumber)) { dcdr[Srcnumber].answerTime = dtAnswerTime; } |
in call-hangup-events , add
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 |
DateTime dtAnswerTime = e.DateReceived; string Srcnumber = e.CallerIdNum; if (dcdr.ContainsKey(Srcnumber)) { dcdr[Srcnumber].hangupDate = dtAnswerTime; var secDiff = (dcdr[Srcnumber].hangupDate - dcdr[Srcnumber].answerTime).TotalSeconds; if (secDiff > 1) { this.Invoke((MethodInvoker)delegate { textBox2.Text = (int.Parse(textBox2.Text) + 1).ToString(); }); this.Invoke((MethodInvoker)delegate { textBox3.Text = (double.Parse(secDiff.ToString()) + double.Parse(textBox3.Text)).ToString(); }); return; } else { return; } } |
textbox2 and textbox3 use to write calls and durations
如何实现周期性的点击按钮
in winform class , define
1 |
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); |
in construct function , write :
1 2 |
timer.Interval = 30000; timer.Tick += new EventHandler(timer_Tick); |
add function
1 2 3 4 5 6 |
void timer_Tick(object sender, EventArgs e) { dcdr.Clear(); button5.PerformClick(); } |
start timer
1 |
timer.Start(); |