diff --git a/device.go b/device.go index a0cf6a5..6af23c5 100644 --- a/device.go +++ b/device.go @@ -43,6 +43,7 @@ type device struct { afc Afc houseArrest HouseArrest syslogRelay SyslogRelay + diagnosticsRelay DiagnosticsRelay crashReportMover CrashReportMover pcapd Pcapd } @@ -462,6 +463,32 @@ func (d *device) SyslogStop() { d.syslogRelay.Stop() } +func (d *device) Reboot() (err error) { + if _, err = d.lockdownService(); err != nil { + return + } + if d.diagnosticsRelay, err = d.lockdown.DiagnosticsRelayService(); err != nil { + return + } + if err = d.diagnosticsRelay.Reboot(); err != nil { + return + } + return +} + +func (d *device) Shutdown() (err error) { + if _, err = d.lockdownService(); err != nil { + return + } + if d.diagnosticsRelay, err = d.lockdown.DiagnosticsRelayService(); err != nil { + return + } + if err = d.diagnosticsRelay.Shutdown(); err != nil { + return + } + return +} + func (d *device) PcapdService() (pcapd Pcapd, err error) { // if d.pcapd != nil { // return d.pcapd, nil diff --git a/device_test.go b/device_test.go index 3f2750d..968e2e5 100644 --- a/device_test.go +++ b/device_test.go @@ -143,3 +143,13 @@ func Test_device_Syslog(t *testing.T) { dev.SyslogStop() time.Sleep(200 * time.Millisecond) } + +func Test_device_Reboot(t *testing.T) { + setupDevice(t) + dev.Reboot() +} + +func Test_device_Shutdown(t *testing.T) { + setupDevice(t) + dev.Shutdown() +} diff --git a/diagnosticsrelay.go b/diagnosticsrelay.go new file mode 100644 index 0000000..43f1cda --- /dev/null +++ b/diagnosticsrelay.go @@ -0,0 +1,39 @@ +package giDevice + +import "github.com/electricbubble/gidevice/pkg/libimobiledevice" + +func newDiagnosticsRelay(client *libimobiledevice.DiagnosticsRelayClient) *diagnostics { + return &diagnostics{ + client: client, + } +} + +type diagnostics struct { + client *libimobiledevice.DiagnosticsRelayClient +} + +func (d *diagnostics) Reboot() (err error) { + var pkt libimobiledevice.Packet + if pkt, err = d.client.NewXmlPacket( + d.client.NewBasicRequest("Restart"), + ); err != nil { + return + } + if err = d.client.SendPacket(pkt); err != nil { + return err + } + return +} + +func (d *diagnostics) Shutdown() (err error) { + var pkt libimobiledevice.Packet + if pkt, err = d.client.NewXmlPacket( + d.client.NewBasicRequest("Shutdown"), + ); err != nil { + return + } + if err = d.client.SendPacket(pkt); err != nil { + return err + } + return +} diff --git a/idevice.go b/idevice.go index 36f2261..f338f32 100644 --- a/idevice.go +++ b/idevice.go @@ -66,6 +66,9 @@ type Device interface { Pcap() (packet <-chan []byte, err error) PcapStop() + Reboot() error + Shutdown() error + crashReportMoverService() (crashReportMover CrashReportMover, err error) MoveCrashReport(hostDir string, opts ...CrashReportMoverOption) (err error) @@ -96,6 +99,7 @@ type Lockdown interface { AfcService() (afc Afc, err error) HouseArrestService() (houseArrest HouseArrest, err error) SyslogRelayService() (syslogRelay SyslogRelay, err error) + DiagnosticsRelayService() (diagnostics DiagnosticsRelay, err error) CrashReportMoverService() (crashReportMover CrashReportMover, err error) } @@ -205,6 +209,12 @@ type Pcapd interface { Packet() <-chan []byte Stop() } + +type DiagnosticsRelay interface { + Reboot() error + Shutdown() error +} + type CrashReportMover interface { Move(hostDir string, opts ...CrashReportMoverOption) (err error) walkDir(dirname string, fn func(path string, info *AfcFileInfo)) (err error) diff --git a/lockdown.go b/lockdown.go index 718a823..057aac6 100644 --- a/lockdown.go +++ b/lockdown.go @@ -457,6 +457,17 @@ func (c *lockdown) PcapdService() (pcapd Pcapd, err error) { return newPcapdClient(pcapdClient), nil } +func (c *lockdown) DiagnosticsRelayService() (diagnostics DiagnosticsRelay, err error) { + var innerConn InnerConn + if innerConn, err = c._startService(libimobiledevice.DiagnosticsRelayServiceName, nil); err != nil { + return nil, err + } + diagnosticsRelayClient := libimobiledevice.NewDiagnosticsRelayClient(innerConn) + diagnostics = newDiagnosticsRelay(diagnosticsRelayClient) + + return +} + func (c *lockdown) CrashReportMoverService() (crashReportMover CrashReportMover, err error) { var innerConn InnerConn if innerConn, err = c._startService(libimobiledevice.CrashReportMoverServiceName, nil); err != nil { diff --git a/pkg/libimobiledevice/diagnosticsrelay.go b/pkg/libimobiledevice/diagnosticsrelay.go new file mode 100644 index 0000000..f38b416 --- /dev/null +++ b/pkg/libimobiledevice/diagnosticsrelay.go @@ -0,0 +1,39 @@ +package libimobiledevice + +const ( + DiagnosticsRelayServiceName = "com.apple.mobile.diagnostics_relay" +) + +type DiagnosticsRelayBasicRequest struct { + Request string `plist:"Request"` + Label string `plist:"Label"` +} + +func NewDiagnosticsRelayClient(innerConn InnerConn) *DiagnosticsRelayClient { + return &DiagnosticsRelayClient{ + newServicePacketClient(innerConn), + } +} + +type DiagnosticsRelayClient struct { + client *servicePacketClient +} + +func (c *DiagnosticsRelayClient) InnerConn() InnerConn { + return c.client.innerConn +} + +func (c *DiagnosticsRelayClient) NewBasicRequest(relayType string) *DiagnosticsRelayBasicRequest { + return &DiagnosticsRelayBasicRequest{ + Request: relayType, + Label: BundleID, + } +} + +func (c *DiagnosticsRelayClient) NewXmlPacket(req interface{}) (Packet, error) { + return c.client.NewXmlPacket(req) +} + +func (c *DiagnosticsRelayClient) SendPacket(pkt Packet) (err error) { + return c.client.SendPacket(pkt) +}