3 namespace remote
{ namespace diku_mch
{
5 using namespace remote::util
;
7 int MoteHost::clientsock
;
8 int MoteHost::plugpipe
;
10 DeviceManager
MoteHost::devices
;
11 Configuration
MoteHost::config
;
13 void MoteHost::lookForServer()
16 std::string host
= config
.vm
["serverAddress"].as
<std::string
>();
17 uint16_t port
= config
.vm
["serverPort"].as
<uint16_t>();
18 uint64_t secs
= config
.vm
["serverConnectionRetryInterval"].as
<uint64_t>();
20 Log::info("Connecting to %s on port %u...", host
.c_str(), port
);
21 clientsock
= openClientSocket(host
, port
);
22 if (clientsock
>= 0) {
23 Log::info("Connected!");
24 setKeepAlive(clientsock
, 3, 120, 30);
30 } catch (remote::protocols::MMSException e
) {
31 Log::error("Exception: %s", e
.what());
33 } catch (remote::error e
) {
34 Log::error("Exception: %s", e
.what());
36 Log::error("Disconnected");
39 Log::error("Connection failed");
42 Log::info("Reconnecting in %llu seconds...", secs
);
43 usleep(secs
* 1000000);
47 void MoteHost::serviceLoop()
49 std::string eventPipe
= config
.vm
["usbPlugEventPipe"].as
<std::string
>();
52 remove(eventPipe
.c_str());
53 if (mkfifo(eventPipe
.c_str(), 0666) == -1)
54 throw remote::error(errno
, "Failed to make fifo " + eventPipe
);
56 plugpipe
= open(eventPipe
.c_str(), O_RDONLY
| O_NONBLOCK
);
58 throw remote::error(errno
, "Failed to open fifo " + eventPipe
);
60 // the first thing to do is send all current mote information to the server
61 devices
.refresh(config
.vm
["devicePath"].as
<std::string
>());
62 Log::debug("Sending mote list to server");
63 MsgPlugEvent
msgPlugEvent(PLUG_MOTES
);
64 if (makeMoteInfoList(devices
.motes
, msgPlugEvent
.getInfoList())) {
65 HostMsg
hostMsg(msgPlugEvent
);
67 msg
.sendMsg(clientsock
,hostMsg
);
70 Log::debug("Entering service loop");
72 int maxfd
= rebuildFdSet(fdset
);
74 // wait for non-blocking reads on the fds
75 if (select(maxfd
+1, &fdset
, NULL
, NULL
, NULL
) == -1)
78 if (FD_ISSET(clientsock
, &fdset
))
81 if (FD_ISSET(plugpipe
, &fdset
))
84 motemap_t::const_iterator moteI
= devices
.motes
.begin();
86 while (moteI
!= devices
.motes
.end()) {
87 int p
= moteI
->second
->getFd();
88 if (p
> 0 && FD_ISSET(p
, &fdset
))
89 handleMoteData(moteI
->second
);
96 int MoteHost::rebuildFdSet(fd_set
& fdset
)
101 motemap_t::const_iterator moteI
= devices
.motes
.begin();
103 // put in valid mote file descriptors
105 while (moteI
!= devices
.motes
.end())
107 pmote
= moteI
->second
;
111 if (p
> maxp
) {maxp
= p
;}
117 // fd for the connected server
118 FD_SET(clientsock
, &fdset
);
119 if (clientsock
> maxp
) {maxp
= clientsock
;}
120 FD_SET(plugpipe
, &fdset
);
121 if (plugpipe
> maxp
) {maxp
= plugpipe
;}
125 void MoteHost::handlePlugEvent()
128 // for now, just assume that a plug event occured
132 Log::info("Handling plug event");
135 i
= read(plugpipe
,&c
,1);
139 plugpipe
= open(config
.vm
["usbPlugEventPipe"].as
<std::string
>().c_str(),O_RDONLY
| O_NONBLOCK
);
143 devices
.refresh(config
.vm
["devicePath"].as
<std::string
>());
145 MsgPlugEvent
msgUnplugEvent(UNPLUG_MOTES
);
146 if (makeMoteInfoList(devices
.lostMotes
, msgUnplugEvent
.getInfoList()))
148 HostMsg
hostMsg(msgUnplugEvent
);
149 msg
.sendMsg(clientsock
,hostMsg
);
152 MsgPlugEvent
msgPlugEvent(PLUG_MOTES
);
153 if (makeMoteInfoList(devices
.newMotes
,msgPlugEvent
.getInfoList()))
155 HostMsg
hostMsg(msgPlugEvent
);
156 msg
.sendMsg(clientsock
,hostMsg
);
160 bool MoteHost::makeMoteInfoList(motemap_t
& motelist
, MsgMoteConnectionInfoList
& infolist
)
162 motemap_t::const_iterator moteI
;
166 for (moteI
= motelist
.begin(); moteI
!= motelist
.end(); moteI
++) {
167 Mote
*mote
= moteI
->second
;
168 MsgMoteConnectionInfo
info(mote
->getMac(), mote
->getDevicePath(),
169 mote
->getPlatform());
171 infolist
.addMoteInfo(info
);
174 return motelist
.size() > 0 ? true : false;
178 void MoteHost::handleMessage()
180 motemap_t::const_iterator moteI
;
183 if (msg
.nonBlockingRecv(clientsock
))
185 uint8_t* buffer
= msg
.getData();
186 uint32_t buflen
= msg
.getLength();
187 HostMsg
hostMsg(buffer
,buflen
);
189 if (hostMsg
.getType() != HOSTMSGTYPE_HOSTREQUEST
)
190 throw remote::error("Can only handle hostmote messages!");
192 MsgHostRequest
& msgHostRequest
= hostMsg
.getHostRequest();
193 MsgMoteAddresses
& addresses
= msgHostRequest
.getMoteAddresses();
194 buffer
= (uint8_t*)msgHostRequest
.getMessage().getData();
195 buflen
= msgHostRequest
.getMessage().getDataLength();
196 MoteMsg
moteMsg(buffer
,buflen
);
198 moteI
= devices
.motes
.find(addresses
.getMac());
200 if (moteI
== devices
.motes
.end())
202 Log::warn("Mote %s unknown!", addresses
.getMac().c_str());
203 MsgHostConfirm
msgHostConfirm(MSGHOSTCONFIRM_UNKNOWN_MOTE
,addresses
,msgHostRequest
.getMessage());
204 HostMsg
msgReply(msgHostConfirm
);
205 msg
.sendMsg(clientsock
,msgReply
);
209 mote
= moteI
->second
;
211 switch (moteMsg
.getType()) {
212 case MOTEMSGTYPE_REQUEST
:
213 handleRequest(mote
,addresses
,moteMsg
.getRequest());
215 case MOTEMSGTYPE_DATA
:
217 MsgPayload payload
= moteMsg
.getData();
218 mote
->writeBuf((const char*)payload
.getData(),payload
.getDataLength());
222 throw remote::error("Invalid message type!");
227 void MoteHost::handleRequest(Mote
* mote
, MsgMoteAddresses
& addresses
, MsgRequest
& request
)
229 uint8_t command
= request
.getCommand();
232 Log::debug("Mote %s got command=%u", addresses
.getMac().c_str(), command
);
236 case MOTECOMMAND_PROGRAM
:
237 result
= mote
->program(addresses
.getTosAddress(),
238 request
.getFlashImage().getData(),
239 request
.getFlashImage().getDataLength());
240 // don't confirm until programming is done
241 if (result
== SUCCESS
)
244 case MOTECOMMAND_CANCELPROGRAMMING
:
245 Log::info("User cancelling programming");
246 result
= mote
->cancelProgramming();
248 case MOTECOMMAND_STATUS
:
251 case MOTECOMMAND_RESET
:
252 result
= mote
->reset();
254 case MOTECOMMAND_START
:
255 result
= mote
->start();
257 case MOTECOMMAND_STOP
:
258 result
= mote
->stop();
261 Log::error("Unkown command %u", command
);
266 MsgConfirm
msgConfirm(command
, result
, mote
->getStatus());
267 MoteMsg
moteMsg(msgConfirm
);
268 MsgPayload
msgPayload(moteMsg
);
269 MsgHostConfirm
msgHostConfirm(MSGHOSTCONFIRM_OK
,addresses
,msgPayload
);
270 HostMsg
hostMsg(msgHostConfirm
);
272 msg
.sendMsg(clientsock
,hostMsg
);
276 void MoteHost::handleMoteData(Mote
* mote
)
279 ssize_t readlen
= sizeof(buf
);
281 MsgMoteAddresses
msgMoteAddresses(mote
->getMac());
283 while (readlen
== sizeof(buf
)) {
284 readlen
= mote
->readBuf(buf
, sizeof(buf
));
286 Log::debug("'%.*s'", readlen
, buf
);
287 uint32_t len
= readlen
;
289 msgData
.setPayload(len
,(uint8_t*)buf
);
290 MoteMsg
moteMsg(msgData
);
291 MsgPayload
msgPayload(moteMsg
);
292 MsgHostConfirm
msgHostConfirm(MSGHOSTCONFIRM_OK
,msgMoteAddresses
,msgPayload
);
293 HostMsg
hostMsg(msgHostConfirm
);
295 msg
.sendMsg(clientsock
,hostMsg
);
299 // check if we're done programming
301 if (mote
->getStatus() == MOTE_PROGRAMMING
) {
302 Log::info("Programming done!");
303 remove(mote
->getImagePath().c_str());
304 result_t result
= mote
->getChildResult();
305 MsgConfirm
msgConfirm(MOTECOMMAND_PROGRAM
, result
, mote
->getStatus());
306 MoteMsg
moteMsg(msgConfirm
);
307 MsgPayload
msgPayload(moteMsg
);
308 MsgHostConfirm
msgHostConfirm(MSGHOSTCONFIRM_OK
,msgMoteAddresses
,msgPayload
);
309 HostMsg
hostMsg(msgHostConfirm
);
311 msg
.sendMsg(clientsock
,hostMsg
);
317 int MoteHost::main(int argc
,char** argv
)
319 config
.read(argc
,argv
);
320 Log::open("diku_mch", LOG_INFO
);
321 if (config
.vm
["daemonize"].as
<int>()) {
324 Log::error("Failed to fork daemon");
331 Log::info("Running as daemon");
340 MoteHost::lookForServer();
346 int main(int argc
,char** argv
)
348 return remote::diku_mch::MoteHost::main(argc
,argv
);