Code refactoring for xiaomi source

This commit is contained in:
Alex X
2026-01-17 10:06:13 +03:00
parent 9a1eac8ef4
commit 425fcffbe1
5 changed files with 14 additions and 40 deletions
+3 -3
View File
@@ -99,12 +99,12 @@ func getCameraURL(url *url.URL) (string, error) {
// The getMissURL request has a fallback to getP2PURL. // The getMissURL request has a fallback to getP2PURL.
// But for known models we can save one request to the cloud. // But for known models we can save one request to the cloud.
if xiaomi.IsLegacy(model) { if xiaomi.IsLegacy(model) {
return getP2PURL(url) return getLegacyURL(url)
} }
return getMissURL(url) return getMissURL(url)
} }
func getP2PURL(url *url.URL) (string, error) { func getLegacyURL(url *url.URL) (string, error) {
query := url.Query() query := url.Query()
clientPublic, clientPrivate, err := crypto.GenerateKey() clientPublic, clientPrivate, err := crypto.GenerateKey()
@@ -161,7 +161,7 @@ func getMissURL(url *url.URL) (string, error) {
res, err := cloudUserRequest(url.User, "/v2/device/miss_get_vendor", params) res, err := cloudUserRequest(url.User, "/v2/device/miss_get_vendor", params)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no available vendor support") { if strings.Contains(err.Error(), "no available vendor support") {
return getP2PURL(url) return getLegacyURL(url)
} }
return "", err return "", err
} }
-4
View File
@@ -231,10 +231,6 @@ func (s *Session25) msgAckCounters() []byte {
} }
func (s *Session25) handleCh1(cmd []byte) int { func (s *Session25) handleCh1(cmd []byte) int {
// Channel 1 used for two-way audio. It's important:
// - answer on 0000 command with exact config response (can't set simple proto)
// - send 0012 command at start
// - respond on every 0008 command for smooth playback
switch cid := string(cmd[:2]); cid { switch cid := string(cmd[:2]); cid {
case "\x00\x00": // client start case "\x00\x00": // client start
return msgClientStart return msgClientStart
+1 -10
View File
@@ -85,10 +85,7 @@ func xiaofangLogin(conn *tutk.Conn, password string) error {
} }
_, data, err = conn.ReadCommand() _, data, err = conn.ReadCommand()
if err != nil { return err
return err
}
return nil
} }
type Client struct { type Client struct {
@@ -110,14 +107,8 @@ func (c *Client) ReadPacket() (hdr, payload []byte, err error) {
switch hdr[0] { switch hdr[0] {
case tutk.CodecH264, tutk.CodecH265: case tutk.CodecH264, tutk.CodecH265:
payload, err = DecodeVideo(payload, c.key) payload, err = DecodeVideo(payload, c.key)
if err != nil {
return
}
case tutk.CodecAAC: case tutk.CodecAAC:
payload, err = crypto.Decode(payload, c.key) payload, err = crypto.Decode(payload, c.key)
if err != nil {
return
}
} }
} }
return return
+1 -2
View File
@@ -62,7 +62,7 @@ func probe(client *Client) ([]*core.Media, error) {
var vcodec, acodec *core.Codec var vcodec, acodec *core.Codec
for { for {
// 0 5000 // 0 5000 codec
// 2 0000 codec params // 2 0000 codec params
// 4 01 active clients // 4 01 active clients
// 5 34 unknown const // 5 34 unknown const
@@ -83,7 +83,6 @@ func probe(client *Client) ([]*core.Media, error) {
if codec == tutk.CodecH264 { if codec == tutk.CodecH264 {
if h264.NALUType(avcc) == h264.NALUTypeSPS { if h264.NALUType(avcc) == h264.NALUTypeSPS {
vcodec = h264.AVCCToCodec(avcc) vcodec = h264.AVCCToCodec(avcc)
vcodec.FmtpLine = ""
} }
} else { } else {
if h265.NALUType(avcc) == h265.NALUTypeVPS { if h265.NALUType(avcc) == h265.NALUTypeVPS {
+9 -21
View File
@@ -21,7 +21,7 @@ func Dial(host, transport string) (*Conn, error) {
_, isTCP := conn.(*tcpConn) _, isTCP := conn.(*tcpConn)
c := &Conn{ c := &Conn{
conn: conn, Conn: conn,
isTCP: isTCP, isTCP: isTCP,
channels: [4]*dataChannel{ channels: [4]*dataChannel{
newDataChannel(0, 10), nil, newDataChannel(250, 100), nil, newDataChannel(0, 10), nil, newDataChannel(250, 100), nil,
@@ -32,7 +32,7 @@ func Dial(host, transport string) (*Conn, error) {
} }
type Conn struct { type Conn struct {
conn net.Conn net.Conn
isTCP bool isTCP bool
err error err error
@@ -116,7 +116,7 @@ func (c *Conn) worker() {
buf := make([]byte, 1200) buf := make([]byte, 1200)
for { for {
n, err := c.conn.Read(buf) n, err := c.Conn.Read(buf)
if err != nil { if err != nil {
c.err = fmt.Errorf("%s: %w", "cs2", err) c.err = fmt.Errorf("%s: %w", "cs2", err)
return return
@@ -136,7 +136,7 @@ func (c *Conn) worker() {
// For TCP we should send ping every second to keep connection alive. // For TCP we should send ping every second to keep connection alive.
// Based on PCAP analysis: official Mi Home app sends PING every ~1s. // Based on PCAP analysis: official Mi Home app sends PING every ~1s.
if now := time.Now(); now.After(keepaliveTS) { if now := time.Now(); now.After(keepaliveTS) {
_, _ = c.conn.Write([]byte{magic, msgPing, 0, 0}) _, _ = c.Conn.Write([]byte{magic, msgPing, 0, 0})
keepaliveTS = now.Add(time.Second) keepaliveTS = now.Add(time.Second)
} }
@@ -151,7 +151,7 @@ func (c *Conn) worker() {
if pushed >= 0 { if pushed >= 0 {
// For UDP we should send ACK. // For UDP we should send ACK.
ack := []byte{magic, msgDrwAck, 0, 6, magicDrw, ch, 0, 1, seqHI, seqLO} ack := []byte{magic, msgDrwAck, 0, 6, magicDrw, ch, 0, 1, seqHI, seqLO}
_, _ = c.conn.Write(ack) _, _ = c.Conn.Write(ack)
} }
} }
@@ -161,7 +161,7 @@ func (c *Conn) worker() {
} }
case msgPing: case msgPing:
_, _ = c.conn.Write([]byte{magic, msgPong, 0, 0}) _, _ = c.Conn.Write([]byte{magic, msgPong, 0, 0})
case msgPong, msgP2PRdyUDP, msgP2PRdyTCP, msgClose: // skip it case msgPong, msgP2PRdyUDP, msgP2PRdyTCP, msgClose: // skip it
case msgDrwAck: // only for UDP case msgDrwAck: // only for UDP
if c.cmdAck != nil { if c.cmdAck != nil {
@@ -184,18 +184,6 @@ func (c *Conn) Version() string {
return "CS2" return "CS2"
} }
func (c *Conn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
func (c *Conn) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}
func (c *Conn) Close() error {
return c.conn.Close()
}
func (c *Conn) Error() error { func (c *Conn) Error() error {
if c.err != nil { if c.err != nil {
return c.err return c.err
@@ -221,7 +209,7 @@ func (c *Conn) WriteCommand(cmd uint32, data []byte) error {
c.seqCh0++ c.seqCh0++
if c.isTCP { if c.isTCP {
_, err := c.conn.Write(req) _, err := c.Conn.Write(req)
return err return err
} }
@@ -237,7 +225,7 @@ func (c *Conn) WriteCommand(cmd uint32, data []byte) error {
} }
for { for {
if _, err := c.conn.Write(req); err != nil { if _, err := c.Conn.Write(req); err != nil {
return err return err
} }
<-timeout.C <-timeout.C
@@ -278,7 +266,7 @@ func (c *Conn) WritePacket(hdr, payload []byte) error {
copy(req[offset:], hdr) copy(req[offset:], hdr)
copy(req[offset+hdrSize:], hdr) copy(req[offset+hdrSize:], hdr)
_, err := c.conn.Write(req) _, err := c.Conn.Write(req)
return err return err
} }