Skip to content

Commit 904b5af

Browse files
authored
Add deviceinfo service info to info command (danielpaulus#155)
I added two new fields to the info command. The response of hardwareInformation and networkInformation from the instruments service are now in the results if a developer image is mounted. hardWareInformation contains various cpu infos. Here is an example: map[hwCPU64BitCapable:1 hwCPUsubtype:1 hwCPUtype:16777228 numberOfCpus:2 numberOfPhysicalCpus:2 speedOfCpus:0] networkInformation contains a list of all network interfaces on the device. Example: map[en0:Wi-Fi en1:Ethernet Adaptor (en1) en2:Ethernet Adaptor (en2) lo0:Loopback pdp_ip0:Cellular (pdp_ip0) pdp_ip1:Cellular (pdp_ip1) pdp_ip2:Cellular (pdp_ip2) pdp_ip3:Cellular (pdp_ip3) pdp_ip4:Cellular (pdp_ip4)] Those are now part of the ios info command output only if the developer image was mounted on the device.
1 parent 699df0a commit 904b5af

File tree

4 files changed

+94
-44
lines changed

4 files changed

+94
-44
lines changed

ios/instruments/helper.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package instruments
22

33
import (
4+
"fmt"
45
"github.com/danielpaulus/go-ios/ios"
56
dtx "github.com/danielpaulus/go-ios/ios/dtx_codec"
7+
"github.com/danielpaulus/go-ios/ios/nskeyedarchiver"
68
log "github.com/sirupsen/logrus"
79
)
810

@@ -29,3 +31,48 @@ func connectInstruments(device ios.DeviceEntry) (*dtx.Connection, error) {
2931
}
3032
return dtxConn, nil
3133
}
34+
35+
func toMap(msg dtx.Message) (string, map[string]interface{}, error) {
36+
if len(msg.Payload) != 1 {
37+
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v has payload size !=1", msg)
38+
}
39+
selector, ok := msg.Payload[0].(string)
40+
if !ok {
41+
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v payload: %+v wasn't a string", msg, msg.Payload[0])
42+
}
43+
args := msg.Auxiliary.GetArguments()
44+
if len(args) == 0 {
45+
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v has an empty auxiliary dictionary", msg)
46+
}
47+
48+
data, ok := args[0].([]byte)
49+
if !ok {
50+
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v invalid aux", msg)
51+
}
52+
53+
unarchived, err := nskeyedarchiver.Unarchive(data)
54+
if err != nil {
55+
return "", map[string]interface{}{}, err
56+
}
57+
if len(unarchived) == 0 {
58+
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v invalid aux", msg)
59+
}
60+
61+
aux, ok := unarchived[0].(map[string]interface{})
62+
if !ok {
63+
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v auxiliary: %+v didn't contain a map[string]interface{}", msg, msg.Payload[0])
64+
}
65+
66+
return selector, aux, nil
67+
}
68+
69+
func extractMapPayload(message dtx.Message) (map[string]interface{}, error) {
70+
if len(message.Payload) != 1 {
71+
return map[string]interface{}{}, fmt.Errorf("payload of message should have only one element: %+v", message)
72+
}
73+
response, ok := message.Payload[0].(map[string]interface{})
74+
if !ok {
75+
return map[string]interface{}{}, fmt.Errorf("payload type of message should be map[string]interface{}: %+v", message)
76+
}
77+
return response, nil
78+
}

ios/instruments/processlist.go renamed to ios/instruments/instruments_deviceinfo.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,27 @@ func (d DeviceInfoService) NameForPid(pid uint64) error {
3333
return err
3434
}
3535

36+
// HardwareInformation gets some nice extra details from Instruments. Here is an example result for an old iPhone 5:
37+
// map[hwCPU64BitCapable:1 hwCPUsubtype:1 hwCPUtype:16777228 numberOfCpus:2 numberOfPhysicalCpus:2 speedOfCpus:0]
38+
func (d DeviceInfoService) HardwareInformation() (map[string]interface{}, error) {
39+
response, err := d.channel.MethodCall("hardwareInformation")
40+
if err != nil {
41+
return map[string]interface{}{}, err
42+
}
43+
return extractMapPayload(response)
44+
}
45+
46+
// NetworkInformation gets a list of all network interfaces for the device. Example result:
47+
// map[en0:Wi-Fi en1:Ethernet Adaptor (en1) en2:Ethernet Adaptor (en2) lo0:Loopback pdp_ip0:Cellular (pdp_ip0)
48+
// pdp_ip1:Cellular (pdp_ip1) pdp_ip2:Cellular (pdp_ip2) pdp_ip3:Cellular (pdp_ip3) pdp_ip4:Cellular (pdp_ip4)]
49+
func (d DeviceInfoService) NetworkInformation() (map[string]interface{}, error) {
50+
response, err := d.channel.MethodCall("networkInformation")
51+
if err != nil {
52+
return map[string]interface{}{}, err
53+
}
54+
return extractMapPayload(response)
55+
}
56+
3657
func mapToProcInfo(procList []interface{}) []ProcessInfo {
3758
result := make([]ProcessInfo, len(procList))
3859
for i, procMapInt := range procList {

ios/instruments/metrics.go renamed to ios/instruments/instruments_notifications.go

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"github.com/danielpaulus/go-ios/ios"
66
dtx "github.com/danielpaulus/go-ios/ios/dtx_codec"
7-
"github.com/danielpaulus/go-ios/ios/nskeyedarchiver"
87
log "github.com/sirupsen/logrus"
98
"io"
109
"time"
@@ -15,40 +14,6 @@ type channelDispatcher struct {
1514
closeChannel chan struct{}
1615
}
1716

18-
func toMap(msg dtx.Message) (string, map[string]interface{}, error) {
19-
if len(msg.Payload) != 1 {
20-
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v has payload size !=1", msg)
21-
}
22-
selector, ok := msg.Payload[0].(string)
23-
if !ok {
24-
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v payload: %+v wasn't a string", msg, msg.Payload[0])
25-
}
26-
args := msg.Auxiliary.GetArguments()
27-
if len(args) == 0 {
28-
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v has an empty auxiliary dictionary", msg)
29-
}
30-
31-
data, ok := args[0].([]byte)
32-
if !ok {
33-
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v invalid aux", msg)
34-
}
35-
36-
unarchived, err := nskeyedarchiver.Unarchive(data)
37-
if err != nil {
38-
return "", map[string]interface{}{}, err
39-
}
40-
if len(unarchived) == 0 {
41-
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v invalid aux", msg)
42-
}
43-
44-
aux, ok := unarchived[0].(map[string]interface{})
45-
if !ok {
46-
return "", map[string]interface{}{}, fmt.Errorf("error extracting, msg %+v auxiliary: %+v didn't contain a map[string]interface{}", msg, msg.Payload[0])
47-
}
48-
49-
return selector, aux, nil
50-
}
51-
5217
func ListenAppStateNotifications(device ios.DeviceEntry) (func() (map[string]interface{}, error), func() error, error) {
5318
conn, err := connectInstruments(device)
5419
if err != nil {

main.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -343,16 +343,14 @@ The commands work as following:
343343
}
344344
b, _ = arguments.Bool("toggle")
345345
if b {
346-
assistiveTouch(device, "toggle" , force)
346+
assistiveTouch(device, "toggle", force)
347347
}
348348
b, _ = arguments.Bool("get")
349349
if b {
350350
assistiveTouch(device, "get", force)
351351
}
352352
}
353353

354-
355-
356354
b, _ = arguments.Bool("dproxy")
357355
if b {
358356
log.SetFormatter(&log.TextFormatter{})
@@ -960,10 +958,10 @@ func assistiveTouch(device ios.DeviceEntry, operation string, force bool) {
960958

961959
wasEnabled, err := ios.GetAssistiveTouch(device)
962960

963-
if err != nil{
964-
if force && ( operation == "enable" || operation == "disable" ) {
961+
if err != nil {
962+
if force && (operation == "enable" || operation == "disable") {
965963
log.WithFields(log.Fields{"error": err}).Warn("Failed getting current AssistiveTouch status. Continuing anyway.")
966-
} else{
964+
} else {
967965
exitIfError("failed getting current AssistiveTouch status", err)
968966
}
969967
}
@@ -973,20 +971,20 @@ func assistiveTouch(device ios.DeviceEntry, operation string, force bool) {
973971
enable = true
974972
case operation == "disable":
975973
enable = false
976-
case operation == "toggle":
974+
case operation == "toggle":
977975
enable = !wasEnabled
978976
default: // get
979977
enable = wasEnabled
980978
}
981-
if operation != "get" && ( force || wasEnabled != enable ) {
979+
if operation != "get" && (force || wasEnabled != enable) {
982980
err = ios.SetAssistiveTouch(device, enable)
983981
exitIfError("failed setting AssistiveTouch", err)
984982
}
985983
if operation == "get" {
986984
if JSONdisabled {
987985
fmt.Printf("%t\n", enable)
988986
} else {
989-
fmt.Println(convertToJSONString(map[string]bool{"AssistiveTouchEnabled":enable}))
987+
fmt.Println(convertToJSONString(map[string]bool{"AssistiveTouchEnabled": enable}))
990988
}
991989
}
992990
}
@@ -1353,6 +1351,25 @@ func printDeviceInfo(device ios.DeviceEntry) {
13531351
if err != nil {
13541352
exitIfError("failed getting info", err)
13551353
}
1354+
svc, err := instruments.NewDeviceInfoService(device)
1355+
if err != nil {
1356+
log.Debugf("could not open instruments, probably dev image not mounted %v", err)
1357+
}
1358+
if err == nil {
1359+
info, err := svc.NetworkInformation()
1360+
if err != nil {
1361+
log.Debugf("error getting networkinfo from instruments %v", err)
1362+
} else {
1363+
allValues["instruments:networkInformation"] = info
1364+
}
1365+
info, err = svc.HardwareInformation()
1366+
if err != nil {
1367+
log.Debugf("error getting hardwareinfo from instruments %v", err)
1368+
} else {
1369+
allValues["instruments:hardwareInformation"] = info
1370+
}
1371+
}
1372+
13561373
fmt.Println(convertToJSONString(allValues))
13571374
}
13581375

0 commit comments

Comments
 (0)