forked from electricbubble/gidevice
/
amfi.go
71 lines (64 loc) 路 1.76 KB
/
amfi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package libimobiledevice
import (
"net/http"
"strings"
"golang.org/x/xerrors"
)
const (
AmfiServiceName = "com.apple.amfi.lockdown"
DEV_MODE_REVEAL = 0
DEV_MODE_ARM = 1
DEV_MODE_ENABLE = 2
)
type AmfiClient struct {
client *servicePacketClient
}
func NewAmfiClient(innerConn InnerConn) *AmfiClient {
return &AmfiClient{
newServicePacketClient(innerConn),
}
}
func (c *AmfiClient) SendAction(action int) (int, error) {
data := map[string]int{"action": action}
pktOut, _ := c.client.NewXmlPacket(data)
if errSend := c.client.SendPacket(pktOut); errSend != nil {
return http.StatusInternalServerError, errSend
}
if pktIn, errRecv := c.client.ReceivePacket(); errRecv != nil {
return http.StatusInternalServerError, errRecv
} else {
result := map[string]interface{}{}
if errDec := pktIn.Unmarshal(&result); errDec != nil {
return http.StatusInternalServerError, errDec
}
if oErr, bHasErr := result["Error"]; bHasErr {
switch strErr := oErr.(type) {
case string:
if strings.Contains(strErr, "passcode") {
return http.StatusLocked, xerrors.New(strErr)
}
return http.StatusInternalServerError, xerrors.New(strErr)
}
}
if oSuccess, bHasSuccess := result["success"]; bHasSuccess {
switch bSuccess := oSuccess.(type) {
case bool:
if bSuccess {
return http.StatusOK, nil
}
return http.StatusConflict, nil
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
if bSuccess != 0 {
return http.StatusOK, nil
}
return http.StatusConflict, nil
case string:
if bSuccess == "true" || bSuccess == "1" {
return http.StatusOK, nil
}
return http.StatusConflict, nil
}
}
return http.StatusUnprocessableEntity, xerrors.Errorf("Unknown response: %+v", result)
}
}