Add support HomeKit server

This commit is contained in:
Alexey Khit
2023-09-02 06:35:04 +03:00
parent a101387b26
commit f00e646612
18 changed files with 1988 additions and 53 deletions
+1 -4
View File
@@ -32,10 +32,7 @@ func (s *Server) AddSession(session *Session) {
s.mu.Lock()
defer s.mu.Unlock()
if err := session.Local.Init(); err != nil {
return
}
if err := session.Remote.Init(); err != nil {
if err := session.init(); err != nil {
return
}
+83 -31
View File
@@ -2,6 +2,7 @@ package srtp
import (
"net"
"time"
"github.com/pion/rtcp"
"github.com/pion/rtp"
@@ -18,7 +19,12 @@ type Session struct {
Send int // bytes send
conn net.PacketConn // local conn endpoint
addr net.Addr // remote addr
PayloadType uint8
RTCPInterval time.Duration
senderRTCP rtcp.SenderReport
senderTime time.Time
}
type Endpoint struct {
@@ -28,35 +34,89 @@ type Endpoint struct {
MasterSalt []byte
SSRC uint32
addr net.Addr
srtp *srtp.Context
}
func (e *Endpoint) Init() error {
var profile srtp.ProtectionProfile
func (e *Endpoint) init() (err error) {
e.addr = &net.UDPAddr{IP: net.ParseIP(e.Addr), Port: int(e.Port)}
e.srtp, err = srtp.CreateContext(e.MasterKey, e.MasterSalt, profile(e.MasterKey))
return
}
switch len(e.MasterKey) {
func profile(key []byte) srtp.ProtectionProfile {
switch len(key) {
case 16:
profile = srtp.ProtectionProfileAes128CmHmacSha1_80
return srtp.ProtectionProfileAes128CmHmacSha1_80
//case 32:
// return srtp.ProtectionProfileAes256CmHmacSha1_80
}
return 0
}
var err error
e.srtp, err = srtp.CreateContext(e.MasterKey, e.MasterSalt, profile)
return err
func (s *Session) init() error {
if err := s.Local.init(); err != nil {
return err
}
if err := s.Remote.init(); err != nil {
return err
}
s.senderRTCP.SSRC = s.Local.SSRC
s.senderTime = time.Now().Add(s.RTCPInterval)
return nil
}
func (s *Session) WriteRTP(packet *rtp.Packet) (int, error) {
b, err := packet.Marshal()
if s.Local.srtp == nil {
return 0, nil // before init call
}
if now := time.Now(); now.After(s.senderTime) {
s.senderRTCP.NTPTime = uint64(now.UnixNano())
s.senderTime = now.Add(s.RTCPInterval)
_, _ = s.WriteRTCP(&s.senderRTCP)
}
clone := rtp.Packet{
Header: rtp.Header{
Version: 2,
Marker: packet.Marker,
PayloadType: s.PayloadType,
SequenceNumber: packet.SequenceNumber,
Timestamp: packet.Timestamp,
SSRC: s.Local.SSRC,
},
Payload: packet.Payload,
}
b, err := clone.Marshal()
if err != nil {
return 0, err
}
s.senderRTCP.PacketCount++
s.senderRTCP.RTPTime = clone.Timestamp
s.senderRTCP.OctetCount += uint32(len(clone.Payload))
if b, err = s.Local.srtp.EncryptRTP(nil, b, nil); err != nil {
return 0, err
}
return s.conn.WriteTo(b, s.addr)
return s.conn.WriteTo(b, s.Remote.addr)
}
func (s *Session) WriteRTCP(packet rtcp.Packet) (int, error) {
b, err := packet.Marshal()
if err != nil {
return 0, err
}
b, err = s.Local.srtp.EncryptRTCP(nil, b, nil)
if err != nil {
return 0, err
}
return s.conn.WriteTo(b, s.Remote.addr)
}
func (s *Session) ReadRTP(b []byte) {
@@ -77,32 +137,24 @@ func (s *Session) ReadRTP(b []byte) {
}
func (s *Session) ReadRTCP(b []byte) {
header := &rtcp.Header{}
b, err := s.Remote.srtp.DecryptRTCP(nil, b, header)
header := rtcp.Header{}
b, err := s.Remote.srtp.DecryptRTCP(nil, b, &header)
if err != nil {
return
}
if _, err = rtcp.Unmarshal(b); err != nil {
//packets, err := rtcp.Unmarshal(b)
//if err != nil {
// return
//}
//if report, ok := packets[0].(*rtcp.SenderReport); ok {
// log.Printf("[srtp] rtcp type=%d report=%v", header.Type, report)
//}
if header.Type != rtcp.TypeSenderReport {
return
}
if header.Type == rtcp.TypeSenderReport {
_ = s.KeepAlive()
}
}
func (s *Session) KeepAlive() error {
rep := rtcp.ReceiverReport{SSRC: s.Local.SSRC}
b, err := rep.Marshal()
if err != nil {
return err
}
if b, err = s.Local.srtp.EncryptRTCP(nil, b, nil); err != nil {
return err
}
_, err = s.conn.WriteTo(b, s.addr)
return err
receiverRTCP := rtcp.ReceiverReport{SSRC: s.Local.SSRC}
_, _ = s.WriteRTCP(&receiverRTCP)
}