{"record":{"id":"aa25e799a7e41b75","repo":"AlexxIT/go2rtc","slug":"can-t-connect","errorCode":null,"errorMessage":"can't connect","messagePattern":"can't connect","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/roborock/client.go","lineNumber":194,"sourceCode":"\tfor {\n\t\tselect {\n\t\tcase <-ticker.C:\n\t\t\t// 7. Receive remote candidates\n\t\t\tif pc.ICEConnectionState() == pion.ICEConnectionStateCompleted {\n\t\t\t\tticker.Stop()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif ice, _ := c.GetDeviceICE(); ice != nil {\n\t\t\t\tfor _, candidate := range ice {\n\t\t\t\t\t_ = c.conn.AddCandidate(candidate)\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase ok := <-connected:\n\t\t\t// 8. Wait connected result (true or false)\n\t\t\tif !ok {\n\t\t\t\treturn errors.New(\"can't connect\")\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\nfunc (c *Client) CheckHomesecPassword() (err error) {\n\tvar ok bool\n\n\tparams := `{\"password\":\"` + c.pin + `\"}`\n\tif err = c.iot.Call(\"check_homesec_password\", params, &ok); err != nil {\n\t\treturn\n\t}\n\n\tif !ok {\n\t\treturn errors.New(\"wrong pin code\")\n\t}","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/roborock/client.go#L176-L212","documentation":"After exchanging SDP and ICE candidates, Connect waits on a `connected` channel for the final result of the WebRTC handshake. A `false` value (peer connection failed to establish) yields \"can't connect\".","triggerScenarios":"The WebRTC peer connection with the roborock camera signals failure instead of success — ICE candidates never connect, DTLS handshake fails, or the camera aborts the session.","commonSituations":"Network/NAT incompatibility preventing UDP connectivity to the camera; camera rejecting the offer because it is busy; firmware not supporting the negotiated media.","solutions":["Check UDP connectivity/firewall between client and camera network","Retry the connection; transient ICE failures are common","Make sure the camera is not occupied by another viewer","Update device firmware via the Roborock app"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if !udpOutboundAllowed() {\n    return errors.New(\"roborock camera streaming requires outbound UDP for WebRTC\")\n}","typeGuard":null,"tryCatchPattern":"err := client.Connect(ctx)\nif err != nil && err.Error() == \"can't connect\" {\n    if err = retryConnect(ctx, client, 3); err != nil {\n        return fmt.Errorf(\"webrtc to camera failed: %w\", err)\n    }\n}","preventionTips":["Open UDP egress toward the camera network","Retry transient ICE failures with backoff","Update camera/vacuum firmware if handshakes consistently fail"],"tags":["webrtc","connection-failed","roborock"],"backgroundTag":"webrtc-connection-failed","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}