Files
go-sip/cmd/sip-call/main.go
T

74 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// sip-call is a standalone, operator-invoked Asterisk line test. It does not
// import the Agent/Dispatcher commands or require a business configuration.
package main
import (
"context"
"errors"
"fmt"
"git.ipao.vip/rogee/go-sip/internal/sipcall"
"github.com/spf13/cobra"
"io"
"os"
"os/signal"
"syscall"
)
type callRunner func(context.Context, sipcall.Config, string, bool) (*sipcall.Report, error)
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
if err := newRootCommand(sipcall.Run).ExecuteContext(ctx); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func newRootCommand(run callRunner) *cobra.Command {
var debug bool
var file string
root := &cobra.Command{Use: "sip-call", Short: "单通 Asterisk 外呼线路测试(不接 AI)", SilenceUsage: true, SilenceErrors: true, RunE: func(*cobra.Command, []string) error {
return errors.New("请使用 sip-call call --sip <线路.env> <原始号码>")
}}
root.PersistentFlags().BoolVarP(&debug, "debug", "D", false, "开启本通抓包和 SIP/RTP 证据提取;缺少工具或权限就拒绝拨号")
call := &cobra.Command{Use: "call --sip <线路.env> <原始号码>", Short: "自动临时配置线路,只拨一次,接通后短暂保持并挂断", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error {
c, err := sipcall.LoadConfig(file)
if err != nil {
return err
}
if _, err = c.Route(args[0]); err != nil {
return err
}
result, runErr := run(cmd.Context(), c, args[0], debug)
if result != nil {
runErr = errors.Join(runErr, printReport(cmd.OutOrStdout(), result))
}
return runErr
}}
call.Flags().StringVar(&file, "sip", "", "线路 ENV 文件(0600;不执行 shell)")
if err := call.MarkFlagRequired("sip"); err != nil {
panic(err)
}
root.AddCommand(call)
return root
}
func printReport(out io.Writer, r *sipcall.Report) error {
status := map[string]string{"connected": "已接通并确认结束", "not_connected": "未接通", "not_dialed": "未拨号", "unknown": "状态不明,禁止自动重拨", "failed": "失败(详情见结果文件)"}[r.Status]
if status == "" {
status = "状态不明"
}
_, err := fmt.Fprintf(out, "结论:%s\n线路:%s (%s)\n主叫:%s\n原始被叫:%s\n线路被叫:%s\n详情:%s\n", status, r.Line, r.Server, r.CallerID, r.Callee, r.DialedCallee, r.Directory+"/result.json")
if r.Evidence != nil {
code := "未观测到最终响应"
if r.Evidence.FinalINVITECode != 0 {
code = fmt.Sprint(r.Evidence.FinalINVITECode)
}
_, e := fmt.Fprintf(out, "抓包:%s\nSHA-256:%s\nSIP 时间线:%s\n原始 INVITE 最终响应:%s\n媒体观察:%s\n", r.Evidence.PCAP, r.Evidence.PCAPSHA256, r.Evidence.SIPTimeline, code, r.Evidence.RTPStatus)
err = errors.Join(err, e)
} else {
_, e := fmt.Fprintln(out, "抓包:未启用(使用 --debug/-D 开启);没有抓包链路证据或媒体验证。")
err = errors.Join(err, e)
}
return err
}