homer

package
v0.49.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CalculateMOS added in v0.38.0

func CalculateMOS(latencyMS, jitterMS, lossPercent float64) float64

CalculateMOS computes a Mean Opinion Score estimate using the E-model approximation. Parameters: one-way latency (ms), jitter (ms), packet loss (%). Returns a value clamped to [1.0, 4.5].

func DeriveRoute added in v0.35.0

func DeriveRoute(msgs []CallRecord) [][2]string

DeriveRoute extracts unique IP hop pairs from a call's messages. Returns pairs of [src, dst] IPs in the order they first appear.

func ExtractSDP added in v0.35.0

func ExtractSDP(raw string) string

ExtractSDP returns the SDP body (everything after the first blank line), or "".

func ExtractSDPMedia added in v0.39.0

func ExtractSDPMedia(raw string) string

ExtractSDPMedia extracts a compact media description from an SDP body embedded in a raw SIP message. Returns e.g. "PCMA :17818" (codec + port) or "" if no SDP or no audio media line.

func ExtractSIPAllHeaders added in v0.35.0

func ExtractSIPAllHeaders(raw string) map[string]string

ExtractSIPAllHeaders returns all SIP headers as map[canonicalName]value. Stops at empty line. Skips the request/status line (first line).

func ExtractSIPHeader added in v0.35.0

func ExtractSIPHeader(raw string, header string) string

ExtractSIPHeader finds the value of a SIP header in a raw message body. Returns "" if not found. Header matching is case-insensitive. Stops at the first empty line (end of headers / start of SDP body).

func ExtractSIPHeadersByPrefix added in v0.35.0

func ExtractSIPHeadersByPrefix(raw string, prefix string) map[string]string

ExtractSIPHeadersByPrefix returns all headers whose name starts with prefix (case-insensitive). Returns map[canonicalHeaderName]value. Stops at empty line.

func FormatRoute added in v0.35.0

func FormatRoute(pairs [][2]string) string

FormatRoute formats IP hop pairs into a compact chain like "A → B → C". Collapses consecutive hops that share an IP endpoint.

func FormatUserAgent added in v0.34.0

func FormatUserAgent(ua string) string

FormatUserAgent transforms raw SIP User-Agent strings into compact display forms. "Asterisk PBX 11.13.1~dfsg-2+deb8u4" → "* 11.13.1" "FPBX-15.0.16.75(16.13.0)" → "FPBX 16.13.0"

func ParseQuery added in v0.34.0

func ParseQuery(input string) (string, error)

ParseQuery parses a user query string and returns the Homer smart input equivalent. Field names are validated and mapped to Homer's internal column names. Returns an error for unknown fields or invalid syntax.

Types

type Alias

type Alias struct {
	ID        float64 `json:"id"`
	IP        string  `json:"ip"`
	Port      float64 `json:"port"`
	Mask      float64 `json:"mask"`
	Alias     string  `json:"alias"`
	Status    bool    `json:"status"`
	CaptureID string  `json:"captureID"`
}

Alias represents a Homer IP/port alias

type CallRecord

type CallRecord struct {
	ID         float64 `json:"id"`
	Date       int64   `json:"create_date"`
	MicroTS    int64   `json:"micro_ts"`
	Protocol   float64 `json:"protocol"`
	SourceIP   string  `json:"srcIp"`
	SourcePort float64 `json:"srcPort"`
	DestIP     string  `json:"dstIp"`
	DestPort   float64 `json:"dstPort"`
	CallID     string  `json:"sid"`
	Method     string  `json:"method"`
	MethodText string  `json:"method_text"`
	FromUser   string  `json:"from_user"`
	ToUser     string  `json:"to_user"`
	RuriUser   string  `json:"ruri_user"`
	UserAgent  string  `json:"user_agent"`
	CSeq       string  `json:"cseq"`
	Status     float64 `json:"status"`
	AliasSrc   string  `json:"aliasSrc"`
	AliasDst   string  `json:"aliasDst"`
	Table      string  `json:"table"`
}

CallRecord represents a raw call record from the Homer API

type CallSummary added in v0.34.0

type CallSummary struct {
	CallID    string        `json:"call_id"`
	StartTime time.Time     `json:"start_time"`
	EndTime   time.Time     `json:"end_time"`
	Duration  time.Duration `json:"duration"`
	Caller    string        `json:"caller"`
	Callee    string        `json:"callee"`
	Direction string        `json:"direction,omitempty"` // "IN", "OUT", or ""
	Status    string        `json:"status"`              // "answered", "busy", "cancelled", "no answer", "failed", "ringing"
	MsgCount  int           `json:"msg_count"`
	Messages  []CallRecord  `json:"-"`
}

CallSummary represents a grouped view of a SIP call (all messages sharing one Call-ID)

func GroupCalls added in v0.34.0

func GroupCalls(records []CallRecord, number string) []CallSummary

GroupCalls groups raw SIP messages by Call-ID and produces call summaries. If number is non-empty, direction is detected relative to that number.

type Client

type Client struct {
	Debug bool
	// contains filtered or unexported fields
}

Client wraps the Homer 7.x REST API

func NewClient

func NewClient(baseURL string) *Client

NewClient creates a new Homer API client

func (*Client) Authenticate

func (c *Client) Authenticate(username, password string) error

Authenticate logs in to Homer and stores the JWT token

func (*Client) ExportPCAP

func (c *Client) ExportPCAP(params SearchParams) ([]byte, error)

ExportPCAP exports call messages as a PCAP file

func (*Client) FetchCalls added in v0.34.0

func (c *Client) FetchCalls(params SearchParams, number string, maxCalls int) ([]CallSummary, error)

FetchCalls discovers calls matching the search parameters. Returns up to maxCalls results.

Uses bounded backward pagination (up to maxBatches × batchLimit messages), walking backwards in time to discover unique Call-IDs. Messages are grouped by Call-ID to produce call summaries.

func (*Client) GetQoS added in v0.38.0

func (c *Client) GetQoS(params SearchParams, searchData []CallRecord) (*QoSResult, error)

GetQoS fetches RTCP quality-of-service reports for the given call records.

func (*Client) GetTransaction added in v0.35.0

func (c *Client) GetTransaction(params SearchParams, searchData []CallRecord) (*TransactionResult, error)

GetTransaction fetches full SIP message details (including raw bodies) for a call. This uses the /api/v3/call/transaction endpoint which requires search results (IDs + callIDs) from a prior SearchCalls query.

func (*Client) ListAliases

func (c *Client) ListAliases() ([]Alias, error)

ListAliases returns all configured IP/port aliases

func (*Client) SearchCalls

func (c *Client) SearchCalls(params SearchParams) (*SearchResult, error)

SearchCalls searches for SIP calls matching the given parameters

func (*Client) TestConnection

func (c *Client) TestConnection() error

TestConnection verifies the Homer API is reachable (unauthenticated health check)

type QoSData added in v0.38.0

type QoSData struct {
	Data  []QoSReport `json:"data"`
	Total int         `json:"total"`
}

QoSData holds a list of QoS reports

type QoSReport added in v0.38.0

type QoSReport struct {
	ID            int             `json:"id"`
	SrcIP         string          `json:"srcIp"`
	SrcPort       int             `json:"srcPort"`
	DstIP         string          `json:"dstIp"`
	DstPort       int             `json:"dstPort"`
	CallID        string          `json:"sid"`
	CorrelationID string          `json:"correlation_id"`
	CreateDate    string          `json:"create_date"`
	Proto         string          `json:"proto"`
	TimeSeconds   int64           `json:"timeSeconds"`
	TimeUseconds  int64           `json:"timeUseconds"`
	Raw           string          `json:"raw"`
	Node          json.RawMessage `json:"node"`
}

QoSReport represents a single RTCP/RTP report from Homer. The transport metadata (IPs, ports) is at the top level. The RTCP message data is in the Raw field as a JSON string that must be decoded separately via ParseMessage().

func (QoSReport) CreateTime added in v0.38.0

func (r QoSReport) CreateTime() time.Time

CreateTime parses the create_date string into a time.Time.

func (QoSReport) ParseMessage added in v0.38.0

func (r QoSReport) ParseMessage() (RTCPMessage, error)

ParseMessage decodes the Raw JSON string into an RTCPMessage.

type QoSResult added in v0.38.0

type QoSResult struct {
	RTCP QoSData `json:"rtcp"`
	RTP  QoSData `json:"rtp"`
}

QoSResult holds the response from a QoS report query

type RTCPMessage added in v0.38.0

type RTCPMessage struct {
	Type              int               `json:"type"` // 200=SR, 201=RR, 202=SDES
	SSRC              uint32            `json:"ssrc"`
	ReportCount       int               `json:"report_count"`
	SenderInformation SenderInformation `json:"sender_information"`
	ReportBlocks      []ReportBlock     `json:"report_blocks"`
}

RTCPMessage holds decoded RTCP message fields from the raw JSON string.

type ReportBlock added in v0.38.0

type ReportBlock struct {
	SourceSSRC   uint32  `json:"source_ssrc"`
	FractionLost float64 `json:"fraction_lost"`
	PacketsLost  int     `json:"packets_lost"`
	HighestSeqNo uint32  `json:"highest_seq_no"`
	IAJitter     uint32  `json:"ia_jitter"`
	LSR          uint32  `json:"lsr"`
	DLSR         uint32  `json:"dlsr"`
}

ReportBlock holds a single RTCP report block

type SearchParams

type SearchParams struct {
	From       time.Time
	To         time.Time
	SmartInput string
	CallID     string
	Limit      int
}

SearchParams holds search query parameters for Homer API calls

type SearchRecord added in v0.34.0

type SearchRecord struct {
	Date      time.Time `json:"date"`
	SrcIP     string    `json:"src_ip"`
	SrcPort   int       `json:"src_port"`
	DstIP     string    `json:"dst_ip"`
	DstPort   int       `json:"dst_port"`
	Method    string    `json:"method"`
	FromUser  string    `json:"from_user"`
	ToUser    string    `json:"to_user"`
	CallID    string    `json:"call_id"`
	SessionID string    `json:"session_id"`
	UserAgent string    `json:"user_agent"`
	CSeq      string    `json:"cseq"`
}

SearchRecord is the clean output type for search results. Used by both table and JSON/JSONL output.

func ToSearchRecords added in v0.34.0

func ToSearchRecords(records []CallRecord) []SearchRecord

ToSearchRecords converts raw API records to clean SearchRecord values.

type SearchResult

type SearchResult struct {
	Data []CallRecord `json:"data"`
}

SearchResult holds the response from a call search

func MergeSearchResults added in v0.34.0

func MergeSearchResults(a, b *SearchResult) *SearchResult

MergeSearchResults deduplicates two search results by message ID.

type SenderInformation added in v0.38.0

type SenderInformation struct {
	Packets          uint32 `json:"packets"`
	Octets           uint32 `json:"octets"`
	NTPTimestampSec  uint32 `json:"ntp_timestamp_sec"`
	NTPTimestampUSec uint32 `json:"ntp_timestamp_usec"`
	RTPTimestamp     uint32 `json:"rtp_timestamp"`
}

SenderInformation holds sender report statistics

type StreamKey added in v0.38.0

type StreamKey struct {
	SrcIP   string
	SrcPort int
	DstIP   string
	DstPort int
}

StreamKey identifies a unique media stream by its endpoints

type StreamMetrics added in v0.38.0

type StreamMetrics struct {
	SrcIP       string    `json:"src_ip"`
	SrcPort     int       `json:"src_port"`
	DstIP       string    `json:"dst_ip"`
	DstPort     int       `json:"dst_port"`
	Reports     int       `json:"reports"`
	Packets     uint32    `json:"packets"`
	PacketsLost int       `json:"packets_lost"`
	LossPercent float64   `json:"loss_percent"`
	AvgJitterMS float64   `json:"avg_jitter_ms"`
	MaxJitterMS float64   `json:"max_jitter_ms"`
	MOS         float64   `json:"mos"`
	FirstReport time.Time `json:"first_report"`
	LastReport  time.Time `json:"last_report"`
}

StreamMetrics holds aggregated quality metrics for a single media stream

func AggregateStreams added in v0.38.0

func AggregateStreams(qos *QoSResult, clockRate int, defaultLatencyMS float64) []StreamMetrics

AggregateStreams groups RTCP reports by media stream and computes per-stream metrics. clockRate is the RTP clock rate in Hz (typically 8000 for G.711). defaultLatencyMS is the assumed one-way network latency in ms for MOS calculation.

type TransactionMessage added in v0.35.0

type TransactionMessage struct {
	ID         int             `json:"id"`
	CallID     string          `json:"sid"`
	Method     string          `json:"method,omitempty"`
	SrcIP      string          `json:"srcIp"`
	SrcPort    int             `json:"srcPort"`
	DstIP      string          `json:"dstIp"`
	DstPort    int             `json:"dstPort"`
	CreateDate int64           `json:"create_date"`
	MicroTS    int64           `json:"micro_ts"`
	Raw        string          `json:"raw"`
	FromUser   string          `json:"from_user,omitempty"`
	ToUser     string          `json:"to_user,omitempty"`
	CSeq       string          `json:"cseq,omitempty"`
	Protocol   int             `json:"protocol"`
	Profile    string          `json:"profile,omitempty"`
	DBNode     string          `json:"dbnode"`
	Node       json.RawMessage `json:"node"` // string or []string depending on Homer version
}

TransactionMessage represents a SIP message with its raw content. The transaction endpoint also returns RTCP/RTP messages (profile "5_default", "35_default") which lack SIP-specific fields like Method. Use IsSIP() to filter.

func (TransactionMessage) IsSIP added in v0.35.0

func (m TransactionMessage) IsSIP() bool

IsSIP returns true if this is a SIP message (not RTCP/RTP/QoS).

type TransactionResult added in v0.35.0

type TransactionResult struct {
	Data struct {
		Messages []TransactionMessage `json:"messages"`
	} `json:"data"`
	Total int `json:"total"`
}

TransactionResult holds the response from a call transaction query

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL