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
|
#include "JobQueue.hpp"
#include "UpdateFactory.hpp"
void Queue::AddJob(const Job& job, const JobPriority& priority)
{
wxMutexLocker lock(m_MutexQueue);
m_Jobs.insert(std::make_pair(priority, job));
m_QueueCount.Post();
}
Job Queue::Pop()
{
Job element;
m_QueueCount.Wait();
m_MutexQueue.Lock();
element = (m_Jobs.begin())->second;
m_Jobs.erase(m_Jobs.begin());
m_MutexQueue.Unlock();
return element;
}
void Queue::Report(const Job::JobEvents& cmd, const wxString& sArg, int iArg)
{
wxCommandEvent evt(wxEVT_THREAD, cmd);
evt.SetString(sArg);
evt.SetInt(iArg);
m_pParent->AddPendingEvent(evt);
}
void Queue::ReportDone(const JobReport& jobReport, const wxString& sArg, int iArg)
{
wxCommandEvent evt(wxEVT_THREAD, Job::eID_THREAD_JOB_DONE);
evt.SetString(sArg);
evt.SetInt(iArg);
evt.SetClientObject(new JobReport(jobReport));
m_pParent->AddPendingEvent(evt);
}
wxThread::ExitCode WorkerThread::doWork()
{
Sleep(1000);
Job::JobEvents iErr;
m_pQueue->Report(Job::eID_THREAD_STARTED, wxEmptyString, m_ID);
try { while(true) OnJob(); }
catch (Job::JobEvents& i) { m_pQueue->Report(iErr=i, wxEmptyString, m_ID); }
return (wxThread::ExitCode) iErr;
}
void WorkerThread::doJob()
{
int rv;
std::time_t jobStart, jobEnd;
unsigned diffTime;
std::string err;
UpdateFactory uf;
Job job = m_pQueue->Pop();
m_pQueue->incBusyWorker();
jobStart = std::time(nullptr);
/* process the job which was started by the GUI */
switch (job.cmdEvent)
{
case Job::eID_THREAD_EXIT:
m_pQueue->decBusyWorker();
throw Job::eID_THREAD_EXIT;
case Job::eID_THREAD_JOB:
Sleep(1000); /* give the UI some time to handle a lot of new Jobs */
/* try to CONNECT to an EnergyManager */
m_pQueue->Report(Job::eID_THREAD_MSG,
wxString::Format(wxT("Job #%d: Connecting to %s:%i"),
job.cmdArgs.jobid, job.cmdArgs.hostname, job.cmdArgs.port), m_ID);
uf.setDest(job.cmdArgs.hostname, job.cmdArgs.port);
uf.setPass(job.cmdArgs.password);
/* try to AUTHENTICATE against an EnergyManager */
rv = uf.doAuth();
/* print REMOTE EnergyManager firmware version (if valid) */
if (uf.getEmcVersion() != EMC_UNKNOWN) {
m_pQueue->Report(Job::eID_THREAD_MSG,
wxString::Format(wxT("Job #%d: Current EnergyManager version: %s"),
job.cmdArgs.jobid, mapEmcVersion(uf.getEmcVersion())), m_ID);
}
/* check if AUTHENTICATE failed */
if (rv != UPDATE_OK) {
mapEmcError(rv, err);
m_pQueue->Report(Job::eID_THREAD_MSGERR,
wxString::Format(wxT("Job #%d: %s."),
job.cmdArgs.jobid, err.c_str()), m_ID);
break;
}
/* load UPDATE IMAGE into memory */
m_pQueue->Report(Job::eID_THREAD_MSG,
wxString::Format(wxT("Job #%d: Loading file \"%s\""),
job.cmdArgs.jobid, job.cmdArgs.update_file), m_ID);
uf.setUpdateFile(job.cmdArgs.update_file.c_str());
rv = uf.loadUpdateFile();
/* validate and check for UPDATE IMAGE firmware version */
if (uf.getFwVersion() == EMC_UNKNOWN) {
m_pQueue->Report(Job::eID_THREAD_MSG,
wxString::Format(wxT("Job #%d: Invalid firmware update file"),
job.cmdArgs.jobid), m_ID);
break;
}
m_pQueue->Report(Job::eID_THREAD_MSG,
wxString::Format(wxT("Job #%d: Firmware image version: %s"),
job.cmdArgs.jobid, mapEmcVersion(uf.getFwVersion())), m_ID);
/* compare REMOTE with UPDATE IMAGE firmware version */
if (!isEmcVersionLowerThen(uf.getEmcVersion(), uf.getFwVersion())) {
m_pQueue->Report(Job::eID_THREAD_MSGERR,
wxString::Format(wxT("Job #%d: Version mismatch (%s >= %s)"),
job.cmdArgs.jobid, mapEmcVersion(uf.getEmcVersion()),
mapEmcVersion(uf.getFwVersion())), m_ID);
break;
}
/* compare succeeded */
if (rv != UPDATE_OK) {
mapEmcError(rv, err);
m_pQueue->Report(Job::eID_THREAD_MSGERR,
wxString::Format(wxT("Job #%d: %s."),
job.cmdArgs.jobid, err.c_str()), m_ID);
break;
}
/* upload UPDATE IMAGE to the REMOTE EnergyManager */
m_pQueue->Report(Job::eID_THREAD_MSG,
wxString::Format(wxT("Job #%d: Uploading file \"%s\""),
job.cmdArgs.jobid, job.cmdArgs.update_file), m_ID);
rv = uf.doUpdate();
/* report any errors during upload */
mapEmcError(rv, err);
if (rv != UPDATE_OK) {
m_pQueue->Report(Job::eID_THREAD_MSGERR,
wxString::Format(wxT("Job #%d: %s."),
job.cmdArgs.jobid, err.c_str()), m_ID);
break;
}
/* done */
m_pQueue->Report(Job::eID_THREAD_MSGOK,
wxString::Format(wxT("Job #%d: %s."),
job.cmdArgs.jobid, err), m_ID);
break;
case Job::eID_THREAD_NULL:
default:
break;
}
/* report consumed time */
jobEnd = std::time(nullptr);
diffTime = std::difftime(jobEnd, jobStart);
m_pQueue->ReportDone(JobReport(diffTime),
wxString::Format(wxT("Job #%d: finished. Time consumed: %umin %usec"),
job.cmdArgs.jobid, (diffTime / 60), (diffTime % 60)), m_ID);
m_pQueue->decBusyWorker();
}
|