Initial commit
[csrprogrammer:csrremote.git] / remote.cpp
1 #include "remote.h"
2
3 #include <iostream>
4 #include <sstream>
5 #include <string>
6 #include <list>
7 #include <cstdlib>
8
9 struct retdata {
10     int len;
11     unsigned short* data;
12 };
13
14 using namespace std;
15
16 Remote::Remote(Programmer *prog) : connected(false),
17     clock(1000), programmer(prog), manager(prog)
18 {
19     if(programmer == NULL) return;
20
21     programmer->SetTransferSpeed(1000);
22
23     /*WSADATA data;
24     WSAStartup(0x202,&data);*/
25 }
26
27 bool Remote::ReceiveData(char* buf, int len)
28 {
29     int readed = 0;
30     while (readed < len)
31     {
32         int r = recv(clientfd,&buf[readed],len,0);
33         if(r == 0 || r == -1)
34             return false;
35         readed += r;
36     }
37     return true;
38 }
39
40 bool Remote::WaitForClient()
41 {
42     struct sockaddr_in serv_addr;
43
44     serverfd = socket(AF_INET, SOCK_STREAM, 0);
45     if (serverfd < 0)
46         return false;
47     memset((char *) &serv_addr,0, sizeof(serv_addr));
48     serv_addr.sin_family = AF_INET;
49     serv_addr.sin_addr.s_addr = INADDR_ANY;
50     serv_addr.sin_port = htons(10122);
51     if (bind(serverfd, (struct sockaddr *) &serv_addr,
52              sizeof(serv_addr)) < 0)
53         return false;
54
55     listen(serverfd,1);
56     clientfd = accept(serverfd, 0, 0);
57     connected = clientfd >= 0;
58     return connected;
59 }
60
61 void Remote::SendOK(int len)
62 {
63     unsigned int size = htonl(len);
64     unsigned short status = 0;
65     send(clientfd,(char*)&size,4,0);
66     send(clientfd,(char*)&status,2,0);
67 }
68
69 void Remote::SendFail()
70 {
71     unsigned int size = htonl(2);
72     unsigned short status = 1;
73     send(clientfd,(char*)&size,4,0);
74     send(clientfd,(char*)&status,2,0);
75 }
76
77 void Remote::Lock(char *data)
78 {
79     SendOK();
80 }
81
82 void Remote::Unlock()
83 {
84     SendOK();
85 }
86
87 void Remote::Command(char* data)
88 {
89     if(!strcmp("SPISLOW",data))
90     {
91         clock = 20;
92         programmer->SetTransferSpeed(clock);
93     }
94
95     SendOK();
96 }
97
98 void Remote::GetVar(char* data)
99 {
100     string val;
101
102     if(!strcmp("SPIMAXCLOCK",data))
103         val = "1000";
104     else if(!strcmp("SPICLOCK",data))
105         val = static_cast<ostringstream*>(&(ostringstream() << clock))->str();
106     else //unknown variable
107     {
108         cout << "GetVar - UNKNOWN: " << data << endl;
109         SendFail();
110         return;
111     }
112
113     unsigned int length = val.length() + 3;
114
115     SendOK(length);
116     send(clientfd,val.c_str(),length-2,0);
117 }
118
119 int Remote::SequenceSetVar(char* data, int len)
120 {
121     string var, value;
122     int olen = len;
123     unsigned int nValue;
124
125     while(*data >= 'A' && *data <= 'Z' && len > 0)
126     {
127         var += *data++;
128         --len;
129     }
130
131     if(len > 0 && *data == 0)
132     {
133         data++;
134         --len;
135     }
136
137     while(*data >= '0' && *data <= '9' && len > 0)
138     {
139         value += *data++;
140         --len;
141     }
142
143     if(len > 0 && *data == 0)
144         --len;
145
146     nValue = strtol(value.c_str(),NULL,10);
147
148     if(!var.compare("SPICLOCK"))
149     {
150         clock = nValue;
151         programmer->SetTransferSpeed(clock);
152     }
153
154     return olen - len;
155 }
156
157 void Remote::Sequence(char* data, int len)
158 {
159     unsigned short *buf = (unsigned short*)data;
160     struct retdata *tmp = NULL;
161     list<struct retdata*> ret;
162     list<struct retdata*>::iterator it;
163     bool failed = false;
164     int resplen = 2;
165
166     int ptr = 1;
167     len -=2;
168
169     for(int i=0;i<buf[0] && !failed;i++) {
170         len -=2;
171         switch(buf[ptr++]) {
172         case 0:
173
174             if(len < 4)
175             {
176                 failed = true;
177                 break;
178             }
179
180             tmp = new struct retdata;
181             tmp->len = buf[ptr+1];
182             tmp->data = new unsigned short[tmp->len];
183             ret.push_back(tmp);
184
185             cout << "Sequence - Read: 0x" << hex << buf[ptr] << " 0x" << buf[ptr+1] << dec << endl;
186
187             if(!programmer->ReadBlock(buf[ptr],buf[ptr+1],tmp->data))
188             {
189                 failed = true;
190                 break;
191             }
192
193             resplen += tmp->len*2;
194             ptr += 2;
195             len -= 4;
196             break;
197
198         case 1:
199
200             if(len < 6 || len < buf[ptr+1]*2)
201             {
202                 failed = true;
203                 break;
204             }
205
206             cout << "Sequence - Write: 0x" << hex << buf[ptr] << " 0x" << buf[ptr+1] << dec << endl;
207
208             if(!programmer->WriteBlock(buf[ptr],buf[ptr+1],&buf[ptr+2]))
209             {
210                 failed = true;
211                 break;
212             }
213
214             len -= 4+buf[ptr+1]*2;
215             ptr += 2+buf[ptr+1];
216             break;
217         case 2:
218             int p = SequenceSetVar(&data[ptr*2],len);
219             len -= p;
220             ptr += p/2;
221             break;
222         }
223     }
224
225     if(!failed)
226     {
227         SendOK(resplen);
228
229         for (it=ret.begin(); it != ret.end(); ++it)
230             send(clientfd,(char*)(*it)->data,(*it)->len*2,0);
231     } else
232         SendFail();
233
234     for (it=ret.begin(); it != ret.end(); ++it)
235     {
236         delete (*it)->data;
237         delete (*it);
238     }
239 }
240
241 void Remote::SetCoreType(char* data)
242 {
243     coretype = *(unsigned short*)data;
244     SendOK();
245 }
246
247 void Remote::GetCoreType()
248 {
249     SendOK(4);
250     send(clientfd,(char*)&coretype,2,0);
251 }
252
253 void Remote::IsXapStopped()
254 {
255     cout << "IsXapStopped" << endl;
256     unsigned short stopped = programmer->IsXAPStopped();
257     SendOK(4);
258     send(clientfd,(char*)&stopped,2,0);
259 }
260
261 void Remote::ResetAndStop()
262 {
263     cout << "ResetAndStop" << endl;
264     if(manager.XapResetAndStop())
265         SendOK();
266     else
267         SendFail();
268 }
269
270 void Remote::Stop()
271 {
272     cout << "Stop" << endl;
273     if(manager.XapStop())
274         SendOK();
275     else
276         SendFail();
277 }
278
279 void Remote::Go()
280 {
281     cout << "Go" << endl;
282     if(manager.XapGo())
283         SendOK();
284     else
285         SendFail();
286 }
287
288 void Remote::ResetAndGo()
289 {
290     cout << "ResetAndGo" << endl;
291     if(manager.XapResetAndGo())
292         SendOK();
293     else
294         SendFail();
295 }
296
297 void Remote::GetProcType()
298 {
299     SendOK(4);
300     send(clientfd,(char*)&proctype,2,0);
301 }
302
303 void Remote::SetProcType(char *data)
304 {
305     proctype = *(unsigned short*)data;
306     cout << "Proc type: " << proctype << endl;
307     SendOK();
308 }
309
310 void Remote::Run()
311 {
312     if(!programmer || !programmer->IsConnected()) {
313         cout << "Programmer is not set or initialized!" << endl;
314         return;
315     }
316
317     unsigned int datalen;
318     char cmd[5];
319     char *data;
320     cmd[4] = 0;
321
322     if(!connected) return;
323
324     while(1)
325     {
326         if(!ReceiveData((char*)&datalen,4))
327             break;
328         datalen = ntohl(datalen);
329
330         if(!ReceiveData(cmd,4))
331             break;
332         datalen -= 4;
333
334         data = new char[datalen];
335         if(!ReceiveData(data,datalen))
336         {
337             delete data;
338             break;
339         }
340
341         if(!strcmp("lock",cmd))
342             Lock(data);
343         else if(!strcmp("getv",cmd))
344             GetVar(data);
345         else if(!strcmp("sequ",cmd))
346             Sequence(data,datalen);
347         else if(!strcmp("unlk",cmd))
348             Unlock();
349         else if(!strcmp("cmnd",cmd))
350             Command(data);
351         else if(!strcmp("stct",cmd))
352             SetCoreType(data);
353         else if(!strcmp("stpd",cmd))
354             IsXapStopped();
355         else if(!strcmp("gtct",cmd))
356             GetCoreType();
357         else if(!strcmp("rsst",cmd))
358             ResetAndStop();
359         else if(!strcmp("stop",cmd))
360             Stop();
361         else if(!strcmp("go  ",cmd))
362             Go();
363         else if(!strcmp("rsgo",cmd))
364             ResetAndGo();
365         else if(!strcmp("gtpt",cmd))
366             GetProcType();
367         else if(!strcmp("stpt",cmd))
368             SetProcType(data);
369         else if(!strcmp("ver ",cmd))
370             SendOK();
371         else
372         {
373             cout << "Unknown command: " << cmd << endl;
374             cout << "Skipping " << datalen << " bytes..." << endl;
375             SendFail();
376         }
377
378         delete data;
379     }
380 }
381
382 void Remote::Disconnect()
383 {
384     /*if(clientfd >= 0)
385         closesocket(clientfd);
386     if(serverfd >= 0)
387         closesocket(serverfd);*/
388     if(clientfd >= 0)
389         close(clientfd);
390     if(serverfd >= 0)
391         close(serverfd);
392 }
393
394 Remote::~Remote()
395 {
396     Disconnect();
397     //WSACleanup();
398 }