FireBirdLib - Topfield TMS PVR TAP Programming Library
FrontPanelComm.c
Go to the documentation of this file.
1#include <pthread.h>
2#include "FBLib_main.h"
3
5byte FPPatchType = 0;
8bool FPPatchInitialized = FALSE;
10byte FPResponse[12];
11
12static pthread_mutex_t FrontMutex;
13static bool FrontHooked = FALSE;
14
15static void (*Front_TxPacket_orig)(byte *Data) = NULL;
16static int (*PutMsgQ_orig)(dword *MsgQ, dword *Data) = NULL;
17
18void Front_TxPacket_hooked(byte *Data)
19{
20 pthread_mutex_lock(&FrontMutex);
21 Front_TxPacket_orig(Data);
22 pthread_mutex_unlock(&FrontMutex);
23}
24
25int PutMsgQ_hooked(dword *MsgQ, dword *Data)
26{
27 int ret;
28 static dword *_MsgQ_Front = NULL;
29
30 //Get the address of the front panel message queue. As this is not a global variable
31 //we have to use the nearest exported variable and add the offset.
32 //Then extract the pointer from it.
33 if(!_MsgQ_Front)
34 {
35 _MsgQ_Front = (dword*)TryResolve("_chKeyInputTime");
36 if(_MsgQ_Front) _MsgQ_Front = (dword*)*(_MsgQ_Front + 2);
37 }
38
39 if((MsgQ == _MsgQ_Front) && (Data[0] == 0x00000001))
40 {
41 //DumpMemoryDword(Data, 16);
42
43 if((Data[1] >> 24) == FPWaitResponse)
44 {
45 FPResponse[ 0] = Data[1] >> 24;
46 FPResponse[ 1] = (Data[1] >> 16) & 0xff;
47 FPResponse[ 2] = (Data[1] >> 8) & 0xff;
48 FPResponse[ 3] = Data[1] & 0xff;
49
50 FPResponse[ 4] = Data[2] >> 24;
51 FPResponse[ 5] = (Data[2] >> 16) & 0xff;
52 FPResponse[ 6] = (Data[2] >> 8) & 0xff;
53 FPResponse[ 7] = Data[2] & 0xff;
54
55 FPResponse[ 8] = Data[3] >> 24;
56 FPResponse[ 9] = (Data[3] >> 16) & 0xff;
57 FPResponse[10] = (Data[3] >> 8) & 0xff;
58 FPResponse[11] = Data[3] & 0xff;
59
61
62 //This is allowed, the firmware handler can handle a NULL pointer
63 MsgQ = NULL;
64 }
65 }
66
67 //Let the original handler do its work
68 ret = PutMsgQ_orig(MsgQ, Data);
69
70 return ret;
71}
72
74{
75 TRACEENTER();
76
77 if(FrontHooked)
78 {
79 if(!UnhookFirmware("Front_TxPacket", Front_TxPacket_hooked, (void*)&Front_TxPacket_orig))
80 LogEntryFBLibPrintf(TRUE, "UnhookFrontTxPacket: failed to unhook Front_TxPacket");
81
82 if(!UnhookFirmware("PutMsgQ", PutMsgQ_hooked, (void*)&PutMsgQ_orig))
83 LogEntryFBLibPrintf(TRUE, "UnhookFrontTxPacket: failed to unhook PutMsgQ");
84
85 FrontHooked = FALSE;
86 TAP_Delay(10);
87 }
88
89 TRACEEXIT();
90}
91
93{
94 TRACEENTER();
95
96 if(!FrontHooked)
97 {
98 if(HookFirmware("Front_TxPacket", Front_TxPacket_hooked, (void*)&Front_TxPacket_orig))
99 {
100 if(HookFirmware("PutMsgQ", PutMsgQ_hooked, (void*)&PutMsgQ_orig))
101 {
102 FrontHooked = TRUE;
103 }
104 else
105 {
106 LogEntryFBLibPrintf(TRUE, "HookFrontTxPacket: failed to hook PutMsgQ");
108 }
109 }
110 else
111 {
112 LogEntryFBLibPrintf(TRUE, "HookFrontTxPacket: failed to hook Front_TxPacket");
113 }
114 TAP_Delay(10);
115 }
116
117 TRACEEXIT();
118 return FrontHooked;
119}
120
122{
123 TRACEENTER();
124
126 {
127 byte Buffer[20];
128 int WaitTimeout, Repeat;
129
130 //The following code sends a command to the front panel and waits for the reply
131 //As the reply is recorded by an different thread, we can block until the reply is received
132
133 Repeat = 2;
134 do
135 {
136 //GetPanelType: Query: F0; Response: F2 <VERSION> <TYPE>
137 Buffer[0] = 0xF0;
138 FPWaitResponse = 0xF2;
139 Front_TxPacket_hooked(Buffer);
140
141 WaitTimeout = 100;
142 while((FPWaitResponse != 0) && WaitTimeout)
143 {
144 TAP_Delay(1);
145 WaitTimeout--;
146 }
147 Repeat--;
148 }while((WaitTimeout == 0) && Repeat);
149
150 if(WaitTimeout == 0)
151 {
153 FPPatchVersion = 0;
154 FPPatchType = 0;
155
156 TRACEEXIT();
157 return FALSE;
158 }
161
162 Repeat = 2;
163 do
164 {
165 //Read the AntiFreeze Option Byte
166 //ReadEEPROM: Query: D2 EAH EAL; Response: D1 <DTA>
167 Buffer[0] = 0xD2;
168 Buffer[1] = 0x01;
169 Buffer[2] = 0xFF;
170 FPWaitResponse = 0xD1;
171 Front_TxPacket_hooked(Buffer);
172
173 WaitTimeout = 100;
174 while((FPWaitResponse != 0) && WaitTimeout)
175 {
176 TAP_Delay(1);
177 WaitTimeout--;
178 }
179 Repeat--;
180 }while((WaitTimeout == 0) && Repeat);
181
182 if(WaitTimeout != 0) FPPatchAntiFreezeOption = FPResponse[1];
183
184 Repeat = 2;
185 do
186 {
187 //Read the PowerRestore Option Byte
188 //ReadEEPROM: Query: D2 EAH EAL; Response: D1 <DTA>
189 Buffer[0] = 0xD2;
190 Buffer[1] = 0x01;
191 Buffer[2] = 0xFE;
192 FPWaitResponse = 0xD1;
193 Front_TxPacket_hooked(Buffer);
194
195 WaitTimeout = 100;
196 while((FPWaitResponse != 0) && WaitTimeout)
197 {
198 TAP_Delay(1);
199 WaitTimeout--;
200 }
201 Repeat--;
202 }while((WaitTimeout == 0) && Repeat);
203
204 if(WaitTimeout != 0) FPPatchPowerRestoreOption = FPResponse[1];
205
206 FPPatchInitialized = TRUE;
207
209 }
210
211 TRACEEXIT();
212 return TRUE;
213}
byte FPWaitResponse
Definition: FrontPanelComm.c:9
bool FP_Initialize(void)
int PutMsgQ_hooked(dword *MsgQ, dword *Data)
bool FPPatchInitialized
Definition: FrontPanelComm.c:8
byte FPPatchPowerRestoreOption
Definition: FrontPanelComm.c:7
byte FPResponse[12]
byte FPPatchType
Definition: FrontPanelComm.c:5
bool HookFrontTxPacket(void)
void UnhookFrontTxPacket(void)
byte FPPatchAntiFreezeOption
Definition: FrontPanelComm.c:6
void Front_TxPacket_hooked(byte *Data)
byte FPPatchVersion
Definition: FrontPanelComm.c:4
bool HookFirmware(char *FirmwareFunctionName, void *RedirectTo, void *PointerToOriginal)
Definition: HookFirmware.c:3
void LogEntryFBLibPrintf(bool Console, char *format,...)
dword TryResolve(char *Function)
Definition: TryResolve.c:5
bool UnhookFirmware(char *FirmwareFunctionName, void *RedirectTo, void *PointerToOriginal)
Definition: UnhookFirmware.c:3
#define TRACEEXIT()
Definition: libFireBird.h:1244
#define TRACEENTER()
Definition: libFireBird.h:1243