-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMeta.cs
More file actions
259 lines (235 loc) · 8.15 KB
/
Copy pathMeta.cs
File metadata and controls
259 lines (235 loc) · 8.15 KB
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
using System;
using System.Text;
using MtkClient.Library.Config;
using MtkClient.Library.Connection;
using MtkClient.Library.State;
using MtkClient.Library.Utils;
namespace MtkClient.Library
{
public class Meta : LogBase
{
private readonly MtkConfig _config;
private readonly Port _port;
private readonly MtkStateManager _stateManager;
public const byte META_MODE = 0x01;
public const byte FACTORY_MODE = 0x02;
public const byte ATE_MODE = 0x05;
// NVRAM commands
public const byte CMD_NVRAM_READ = 0x30;
public const byte CMD_NVRAM_WRITE = 0x31;
public const byte CMD_NVRAM_RESET = 0x32;
// IMEI commands
public const byte CMD_READ_IMEI = 0x40;
public const byte CMD_WRITE_IMEI = 0x41;
public Meta(MtkConfig config, Port port, MtkStateManager stateManager = null,
LogLevel logLevel = LogLevel.Info)
{
InitLogger(logLevel);
_config = config;
_port = port;
_stateManager = stateManager;
}
public bool DetectMetaMode()
{
try
{
// Check if device is in META mode by probing
_port.Cdc.Flush();
var response = _port.UsbRead(4, 500);
if (response != null && response.Length >= 4)
{
string magic = Encoding.ASCII.GetString(response, 0, 4);
if (magic == "META" || magic == "FACT" || magic == "ATE\0")
{
Info($"META mode detected: {magic.TrimEnd('\0')}");
_stateManager?.TransitionTo(DeviceState.MetaMode, "META detected");
return true;
}
}
}
catch { }
return false;
}
public bool EnterMetaMode()
{
Info("Entering META mode...");
try
{
_port.UsbWrite(new byte[] { Preloader.CMD_SET_META_BOOT, META_MODE });
var ack = _port.RWord();
if (ack == Preloader.ACK)
{
Info("META mode entered successfully");
_stateManager?.TransitionTo(DeviceState.MetaMode, "META mode");
return true;
}
Error("Failed to enter META mode");
return false;
}
catch (Exception ex)
{
Error($"META mode error: {ex.Message}");
return false;
}
}
public bool EnterFactoryMode()
{
Info("Entering Factory mode...");
try
{
_port.UsbWrite(new byte[] { Preloader.CMD_SET_META_BOOT, FACTORY_MODE });
var ack = _port.RWord();
if (ack == Preloader.ACK)
{
_stateManager?.TransitionTo(DeviceState.FactoryMode, "Factory mode");
return true;
}
return false;
}
catch (Exception ex)
{
Error($"Factory mode error: {ex.Message}");
return false;
}
}
public bool EnterAteMode()
{
Info("Entering ATE mode...");
try
{
_port.UsbWrite(new byte[] { Preloader.CMD_SET_META_BOOT, ATE_MODE });
var ack = _port.RWord();
if (ack == Preloader.ACK)
{
_stateManager?.TransitionTo(DeviceState.AteMode, "ATE mode");
return true;
}
return false;
}
catch (Exception ex)
{
Error($"ATE mode error: {ex.Message}");
return false;
}
}
public byte[] ReadNvram(int fileId, int offset = 0, int length = 0)
{
try
{
_port.UsbWrite(new byte[] { CMD_NVRAM_READ });
_port.UsbWrite(MtkUtils.Pack32BE((uint)fileId));
_port.UsbWrite(MtkUtils.Pack32BE((uint)offset));
_port.UsbWrite(MtkUtils.Pack32BE((uint)length));
var ack = _port.RWord();
if (ack != Preloader.ACK) return null;
var sizeData = _port.RdWord();
if (sizeData == null) return null;
var data = _port.UsbRead((int)sizeData.Value);
Debug($"NVRAM read: fileId={fileId}, offset=0x{offset:X}, len={data?.Length ?? 0}");
return data;
}
catch (Exception ex)
{
Error($"NVRAM read failed: {ex.Message}");
return null;
}
}
public bool WriteNvram(int fileId, byte[] data, int offset = 0)
{
try
{
_port.UsbWrite(new byte[] { CMD_NVRAM_WRITE });
_port.UsbWrite(MtkUtils.Pack32BE((uint)fileId));
_port.UsbWrite(MtkUtils.Pack32BE((uint)offset));
_port.UsbWrite(MtkUtils.Pack32BE((uint)data.Length));
_port.UsbWrite(data);
var ack = _port.RWord();
if (ack == Preloader.ACK)
{
Debug($"NVRAM written: fileId={fileId}, offset=0x{offset:X}, len={data.Length}");
return true;
}
return false;
}
catch (Exception ex)
{
Error($"NVRAM write failed: {ex.Message}");
return false;
}
}
public string ReadImei(int slot = 0)
{
try
{
_port.UsbWrite(new byte[] { CMD_READ_IMEI });
_port.UsbWrite(MtkUtils.Pack32BE((uint)slot));
var ack = _port.RWord();
if (ack != Preloader.ACK) return null;
var lenData = _port.RdWord();
if (lenData == null) return null;
var imeiBytes = _port.UsbRead((int)lenData.Value);
if (imeiBytes != null)
{
string imei = Encoding.ASCII.GetString(imeiBytes).TrimEnd('\0');
Info($"IMEI slot {slot}: {imei}");
return imei;
}
return null;
}
catch (Exception ex)
{
Error($"Read IMEI failed: {ex.Message}");
return null;
}
}
public bool WriteImei(string imei, int slot = 0)
{
if (string.IsNullOrEmpty(imei) || imei.Length != 15)
{
Error("Invalid IMEI format (must be 15 digits)");
return false;
}
try
{
var imeiBytes = Encoding.ASCII.GetBytes(imei);
_port.UsbWrite(new byte[] { CMD_WRITE_IMEI });
_port.UsbWrite(MtkUtils.Pack32BE((uint)slot));
_port.UsbWrite(MtkUtils.Pack32BE((uint)imeiBytes.Length));
_port.UsbWrite(imeiBytes);
var ack = _port.RWord();
if (ack == Preloader.ACK)
{
Info($"IMEI slot {slot} written: {imei}");
return true;
}
return false;
}
catch (Exception ex)
{
Error($"Write IMEI failed: {ex.Message}");
return false;
}
}
public bool ResetNvram()
{
Info("Resetting NVRAM...");
try
{
_port.UsbWrite(new byte[] { CMD_NVRAM_RESET });
var ack = _port.RWord();
if (ack == Preloader.ACK)
{
Info("NVRAM reset successful");
return true;
}
Error("NVRAM reset failed");
return false;
}
catch (Exception ex)
{
Error($"NVRAM reset failed: {ex.Message}");
return false;
}
}
}
}