1 //
2 // Copyright (c) 2010-2022 Antmicro
3 //
4 //  This file is licensed under the MIT License.
5 //  Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using Antmicro.Migrant;
9 using Antmicro.Migrant.Hooks;
10 using Antmicro.Renode.Core;
11 using Antmicro.Renode.Logging;
12 using Antmicro.Renode.Exceptions;
13 using Antmicro.Renode.Peripherals;
14 using Antmicro.Renode.Peripherals.Wireless;
15 using Antmicro.Renode.Peripherals.CPU;
16 using Antmicro.Renode.Utilities;
17 using Microsoft.Scripting.Hosting;
18 
19 namespace Antmicro.Renode.Hooks
20 {
21     public class PacketInterceptionPythonEngine : PythonEngine
22     {
PacketInterceptionPythonEngine(IRadio radio, string script = null, OptionalReadFilePath filename = null)23         public PacketInterceptionPythonEngine(IRadio radio, string script = null, OptionalReadFilePath filename = null)
24         {
25             if((script == null && filename == null) || (script != null && filename != null))
26             {
27                 throw new ConstructionException("Parameters `script` and `filename` cannot be both set or both unset.");
28             }
29 
30             this.radio = radio;
31             this.script = script;
32             this.filename = filename;
33             machine = radio.GetMachine();
34 
35             InnerInit();
36 
37             Hook = packet =>
38             {
39                 Scope.SetVariable("packet", packet);
40                 Execute(code, error =>
41                 {
42                     this.radio.Log(LogLevel.Error, "Python runtime error: {0}", error);
43                 });
44             };
45         }
46 
47         public Action<byte[]> Hook { get; private set; }
48 
49         [PostDeserialization]
InnerInit()50         private void InnerInit()
51         {
52             Scope.SetVariable("self", radio);
53             Scope.SetVariable("machine", machine);
54             if(script != null)
55             {
56                 var source = Engine.CreateScriptSourceFromString(script);
57                 code = Compile(source);
58             }
59             else if(filename != null)
60             {
61                 var source = Engine.CreateScriptSourceFromFile(filename);
62                 code = Compile(source);
63             }
64         }
65 
66         [Transient]
67         private CompiledCode code;
68         private readonly string script;
69         private readonly string filename;
70         private readonly IRadio radio;
71         private readonly IMachine machine;
72     }
73 }
74