00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include <stdlib.h>
00059 #include <qstringlist.h>
00060 #include <qregexp.h>
00061 #include <qdir.h>
00062 #include <qapplication.h>
00063 #include "util.h"
00064 #include "mythcontext.h"
00065 #include "lcddevice.h"
00066
00067 #include "lcdserver.h"
00068
00069 int debug_level = 0;
00070
00071 LCDServer::LCDServer(int port, QString message, int messageTime)
00072 :QObject()
00073 {
00074 m_lcd = new LCDProcClient(this);
00075 if (!m_lcd->SetupLCD())
00076 {
00077 delete m_lcd;
00078 m_lcd = NULL;
00079 }
00080
00081
00082 m_serverSocket = new LCDServerSocket(port);
00083 connect(m_serverSocket, SIGNAL(newConnect(QSocket *)),
00084 this, SLOT(newConnection(QSocket *)));
00085 connect(m_serverSocket, SIGNAL(endConnect(QSocket *)),
00086 this, SLOT(endConnection(QSocket *)));
00087
00088 m_lastSocket = NULL;
00089
00090
00091 if (debug_level > 0)
00092 VERBOSE(VB_NETWORK, QString("LCDServer: is listening on port %1")
00093 .arg(port));
00094
00095 if (m_lcd)
00096 m_lcd->setStartupMessage(message, messageTime);
00097 }
00098
00099 void LCDServer::newConnection(QSocket *socket)
00100 {
00101 connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
00102
00103 if (debug_level > 0)
00104 VERBOSE(VB_NETWORK, "LCDServer: new connection");
00105
00106 if (m_lcd)
00107 m_lcd->switchToTime();
00108 }
00109
00110 void LCDServer::endConnection(QSocket *socket)
00111 {
00112 socket->close();
00113
00114 if (debug_level > 0)
00115 VERBOSE(VB_NETWORK, "LCDServer: close connection");
00116
00117 if (m_lastSocket == socket)
00118 m_lastSocket = NULL;
00119 }
00120
00121 void LCDServer::readSocket()
00122 {
00123
00124 QSocket *socket = (QSocket *)sender();
00125 m_lastSocket = socket;
00126
00127 while(socket->canReadLine())
00128 {
00129 QString incoming_data = socket->readLine();
00130 incoming_data = incoming_data.replace( QRegExp("\n"), "" );
00131 incoming_data = incoming_data.replace( QRegExp("\r"), "" );
00132 incoming_data.simplifyWhiteSpace();
00133 QStringList tokens = parseCommand(incoming_data);
00134 parseTokens(tokens, socket);
00135 }
00136 }
00137
00138 QStringList LCDServer::parseCommand(QString &command)
00139 {
00140 QStringList tokens;
00141 QString s = "";
00142 QChar c;
00143 bool bInString = false;
00144
00145 for (uint x = 0; x < command.length(); x++)
00146 {
00147 c = command[x];
00148 if (!bInString && c == '"')
00149 bInString = true;
00150 else if (bInString && c == '"')
00151 bInString = false;
00152 else if (!bInString && c == ' ')
00153 {
00154 tokens.append(s);
00155 s = "";
00156 }
00157 else
00158 s = s + c;
00159 }
00160
00161 tokens.append(s);
00162
00163 return tokens;
00164 }
00165
00166 void LCDServer::parseTokens(const QStringList &tokens, QSocket *socket)
00167 {
00168
00169
00170
00171
00172 if (tokens[0] == "HALT" ||
00173 tokens[0] == "QUIT" ||
00174 tokens[0] == "SHUTDOWN")
00175 {
00176 shutDown();
00177 }
00178 else if (tokens[0] == "HELLO")
00179 {
00180 sendConnected(socket);
00181 }
00182 else if (tokens[0] == "SWITCH_TO_TIME")
00183 {
00184 switchToTime(socket);
00185 }
00186 else if (tokens[0] == "SWITCH_TO_MUSIC")
00187 {
00188 switchToMusic(tokens, socket);
00189 }
00190 else if (tokens[0] == "SWITCH_TO_VOLUME")
00191 {
00192 switchToVolume(tokens, socket);
00193 }
00194 else if (tokens[0] == "SWITCH_TO_GENERIC")
00195 {
00196 switchToGeneric(tokens, socket);
00197 }
00198 else if (tokens[0] == "SWITCH_TO_MENU")
00199 {
00200 switchToMenu(tokens, socket);
00201 }
00202 else if (tokens[0] == "SWITCH_TO_CHANNEL")
00203 {
00204 switchToChannel(tokens, socket);
00205 }
00206 else if (tokens[0] == "SWITCH_TO_NOTHING")
00207 {
00208 switchToNothing(socket);
00209 }
00210 else if (tokens[0] == "SET_VOLUME_LEVEL")
00211 {
00212 setVolumeLevel(tokens, socket);
00213 }
00214 else if (tokens[0] == "SET_GENERIC_PROGRESS")
00215 {
00216 setGenericProgress(tokens, socket);
00217 }
00218 else if (tokens[0] == "SET_MUSIC_PROGRESS")
00219 {
00220 setMusicProgress(tokens, socket);
00221 }
00222 else if (tokens[0] == "SET_MUSIC_PLAYER_PROP")
00223 {
00224 setMusicProp(tokens, socket);
00225 }
00226 else if (tokens[0] == "SET_CHANNEL_PROGRESS")
00227 {
00228 setChannelProgress(tokens, socket);
00229 }
00230 else if (tokens[0] == "UPDATE_LEDS")
00231 {
00232 updateLEDs(tokens, socket);
00233 }
00234 else if (tokens[0] == "STOP_ALL")
00235 {
00236 if (m_lcd)
00237 m_lcd->stopAll();
00238 }
00239 else if (tokens[0] == "RESET")
00240 {
00241
00242 if (m_lcd)
00243 m_lcd->reset();
00244 }
00245 else
00246 {
00247 QString did_not_parse = tokens.join(" ");
00248
00249 if (debug_level > 0)
00250 VERBOSE(VB_IMPORTANT, "LCDServer::failed to parse this: "
00251 << did_not_parse);
00252
00253 sendMessage(socket, "HUH?");
00254 }
00255 }
00256
00257 void LCDServer::shutDown()
00258 {
00259 if (debug_level > 0)
00260 VERBOSE(VB_GENERAL, "LCDServer:: shuting down");
00261
00262 delete m_serverSocket;
00263
00264 exit(0);
00265 }
00266
00267 void LCDServer::sendMessage(QSocket *where, const QString &what)
00268 {
00269 QString message = what;
00270 message.append("\n");
00271 where->writeBlock(message.utf8(), message.utf8().length());
00272 }
00273
00274 void LCDServer::sendKeyPress(QString key_pressed)
00275 {
00276 if (debug_level > 0)
00277 VERBOSE(VB_GENERAL, "LCDServer:: send key press: " << key_pressed);
00278
00279
00280 if (m_lastSocket)
00281 sendMessage(m_lastSocket, "KEY " + key_pressed);
00282 }
00283
00284 void LCDServer::sendConnected(QSocket *socket)
00285 {
00286 QString sWidth, sHeight;
00287 int nWidth = 0, nHeight = 0;
00288
00289 if (m_lcd)
00290 {
00291 nWidth = m_lcd->getLCDWidth();
00292 nHeight = m_lcd->getLCDHeight();
00293 }
00294
00295 sWidth = sWidth.setNum(nWidth);
00296 sHeight = sHeight.setNum(nHeight);
00297
00298 sendMessage(socket, "CONNECTED " + sWidth + " " + sHeight);
00299 }
00300
00301 void LCDServer::switchToTime(QSocket *socket)
00302 {
00303 if (debug_level > 0)
00304 VERBOSE(VB_GENERAL, "LCDServer:: SWITCH_TO_TIME");
00305
00306 if (m_lcd)
00307 m_lcd->switchToTime();
00308
00309 sendMessage(socket, "OK");
00310 }
00311
00312 void LCDServer::switchToMusic(const QStringList &tokens, QSocket *socket)
00313 {
00314 if (debug_level > 0)
00315 VERBOSE(VB_GENERAL, "LCDServer: SWITCH_TO_MUSIC");
00316
00317 QString flat = tokens.join(" ");
00318
00319 if (tokens.count() != 4)
00320 {
00321 VERBOSE(VB_IMPORTANT, "LCDServer: bad SWITCH_TO_MUSIC command: " << flat);
00322 sendMessage(socket, "HUH?");
00323 return;
00324 }
00325
00326 if (m_lcd)
00327 m_lcd->switchToMusic(tokens[1], tokens[2], tokens[3]);
00328
00329 sendMessage(socket, "OK");
00330 }
00331
00332 void LCDServer::switchToGeneric(const QStringList &tokens, QSocket *socket)
00333 {
00334 if (debug_level > 0)
00335 VERBOSE(VB_GENERAL, "LCDServer: SWITCH_TO_GENERIC");
00336
00337 QString flat = tokens.join(" ");
00338
00339 if ((tokens.count() - 1) % 5 != 0)
00340 {
00341 VERBOSE(VB_IMPORTANT, "LCDServer: bad no. of args SWITCH_TO_GENERIC "
00342 "command: " << flat);
00343 sendMessage(socket, "HUH?");
00344 return;
00345 }
00346
00347 QPtrList<LCDTextItem> items;
00348 items.setAutoDelete(true);
00349
00350 for (uint x = 1; x < tokens.count(); x += 5)
00351 {
00352 bool bOK;
00353 int row = tokens[x].toInt(&bOK);
00354 if (!bOK)
00355 {
00356 VERBOSE(VB_IMPORTANT, "LCDServer: bad row no. in SWITCH_TO_GENERIC "
00357 "command: " << tokens[x]);
00358 sendMessage(socket, "HUH?");
00359 return;
00360 }
00361
00362 TEXT_ALIGNMENT align;
00363 if (tokens[x + 1] == "ALIGN_LEFT")
00364 align = ALIGN_LEFT;
00365 else if (tokens[x + 1] == "ALIGN_RIGHT")
00366 align = ALIGN_RIGHT;
00367 else if (tokens[x + 1] == "ALIGN_CENTERED")
00368 align = ALIGN_CENTERED;
00369 else
00370 {
00371 VERBOSE(VB_IMPORTANT, "LCDServer: bad align in SWITCH_TO_GENERIC "
00372 "command: " << tokens[x + 1]);
00373 sendMessage(socket, "HUH?");
00374 return;
00375 }
00376
00377 QString text = tokens[x + 2];
00378 QString screen = tokens[x + 3];
00379 bool scrollable;
00380 if (tokens[x + 4] == "TRUE")
00381 scrollable = true;
00382 else if (tokens[x + 4] == "FALSE")
00383 scrollable = false;
00384 else
00385 {
00386 VERBOSE(VB_IMPORTANT, "LCDServer: bad scrollable bool in "
00387 "SWITCH_TO_GENERIC command: " << tokens[x + 4]);
00388 sendMessage(socket, "HUH?");
00389 return;
00390 }
00391
00392 items.append(new LCDTextItem(row, align, text, screen, scrollable));
00393 }
00394
00395 if (m_lcd)
00396 m_lcd->switchToGeneric(&items);
00397
00398 sendMessage(socket, "OK");
00399 }
00400
00401 void LCDServer::switchToChannel(const QStringList &tokens, QSocket *socket)
00402 {
00403 if (debug_level > 0)
00404 VERBOSE(VB_GENERAL, "LCDServer: SWITCH_TO_CHANNEL");
00405
00406 QString flat = tokens.join(" ");
00407
00408 if (tokens.count() != 4)
00409 {
00410 VERBOSE(VB_IMPORTANT, "LCDServer: bad SWITCH_TO_CHANNEL command: "
00411 << flat);
00412 sendMessage(socket, "HUH?");
00413 return;
00414 }
00415
00416 if (m_lcd)
00417 m_lcd->switchToChannel(tokens[1], tokens[2], tokens[3]);
00418
00419 sendMessage(socket, "OK");
00420 }
00421
00422 void LCDServer::switchToVolume(const QStringList &tokens, QSocket *socket)
00423 {
00424 if (debug_level > 0)
00425 VERBOSE(VB_GENERAL, "LCDServer: SWITCH_TO_VOLUME");
00426
00427 QString flat = tokens.join(" ");
00428
00429 if (tokens.count() != 2)
00430 {
00431 VERBOSE(VB_IMPORTANT, "LCDServer: bad SWITCH_TO_VOLUME command: "
00432 << flat);
00433 sendMessage(socket, "HUH?");
00434 return;
00435 }
00436
00437 if (m_lcd)
00438 m_lcd->switchToVolume(tokens[1]);
00439
00440 sendMessage(socket, "OK");
00441 }
00442
00443 void LCDServer::switchToNothing(QSocket *socket)
00444 {
00445 if (debug_level > 0)
00446 VERBOSE(VB_GENERAL, "LCDServer: SWITCH_TO_NOTHING");
00447
00448 if (m_lcd)
00449 m_lcd->switchToNothing();
00450
00451 sendMessage(socket, "OK");
00452 }
00453
00454 void LCDServer::switchToMenu(const QStringList &tokens, QSocket *socket)
00455 {
00456 if (debug_level > 0)
00457 VERBOSE(VB_GENERAL, "LCDServer: SWITCH_TO_MENU: " << tokens.count());
00458
00459 QString flat = tokens.join(" ");
00460
00461 if ((tokens.count() - 3) % 5 != 0)
00462 {
00463 VERBOSE(VB_IMPORTANT, "LCDServer: bad no. of args SWITCH_TO_MENU command: "
00464 << flat);
00465 sendMessage(socket, "HUH?");
00466 return;
00467 }
00468
00469 QString appName = tokens[1];
00470
00471 bool bPopup;
00472 if (tokens[2] == "TRUE")
00473 bPopup = true;
00474 else if (tokens[2] == "FALSE")
00475 bPopup = false;
00476 else
00477 {
00478 VERBOSE(VB_IMPORTANT, "LCDServer: bad popup bool in SWITCH_TO_MENU "
00479 "command: " << tokens[2]);
00480 sendMessage(socket, "HUH?");
00481 return;
00482 }
00483
00484 QPtrList<LCDMenuItem> items;
00485 items.setAutoDelete(true);
00486
00487 for (uint x = 3; x < tokens.count(); x += 5)
00488 {
00489 QString text = tokens[x];
00490
00491 CHECKED_STATE checked;
00492 if (tokens[x + 1] == "CHECKED")
00493 checked = CHECKED;
00494 else if (tokens[x + 1] == "UNCHECKED")
00495 checked = UNCHECKED;
00496 else if (tokens[x + 1] == "NOTCHECKABLE")
00497 checked = NOTCHECKABLE;
00498 else
00499 {
00500 VERBOSE(VB_IMPORTANT, "LCDServer: bad checked state in "
00501 "SWITCH_TO_MENU command: " << tokens[x + 1]);
00502 sendMessage(socket, "HUH?");
00503 return;
00504 }
00505
00506 bool selected;
00507 if (tokens[x + 2] == "TRUE")
00508 selected = true;
00509 else if (tokens[x + 2] == "FALSE")
00510 selected = false;
00511 else
00512 {
00513 VERBOSE(VB_IMPORTANT, "LCDServer: bad selected state in "
00514 "SWITCH_TO_MENU command: " << tokens[x + 2]);
00515 sendMessage(socket, "HUH?");
00516 return;
00517 }
00518
00519 bool scrollable;
00520 if (tokens[x + 3] == "TRUE")
00521 scrollable = true;
00522 else if (tokens[x + 3] == "FALSE")
00523 scrollable = false;
00524 else
00525 {
00526 VERBOSE(VB_IMPORTANT, "LCDServer: bad scrollable bool in "
00527 "SWITCH_TO_MENU command: " << tokens[x + 3]);
00528 sendMessage(socket, "HUH?");
00529 return;
00530 }
00531
00532 bool bOK;
00533 int indent = tokens[x + 4].toInt(&bOK);
00534 if (!bOK)
00535 {
00536 VERBOSE(VB_IMPORTANT, "LCDServer: bad indent in SWITCH_TO_MENU "
00537 "command: " << tokens[x + 4]);
00538 sendMessage(socket, "HUH?");
00539 return;
00540 }
00541
00542 items.append(new LCDMenuItem(selected, checked, text, indent));
00543 }
00544
00545 if (m_lcd)
00546 m_lcd->switchToMenu(&items, appName, bPopup);
00547
00548 sendMessage(socket, "OK");
00549 }
00550
00551 void LCDServer::setChannelProgress(const QStringList &tokens, QSocket *socket)
00552 {
00553 if (debug_level > 0)
00554 VERBOSE(VB_GENERAL, "LCDServer: SET_CHANNEL_PROGRESS");
00555
00556 QString flat = tokens.join(" ");
00557
00558 if (tokens.count() != 2)
00559 {
00560 VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_CHANNEL_PROGRESS command: "
00561 << flat);
00562 sendMessage(socket, "HUH?");
00563 return;
00564 }
00565
00566 bool bOK;
00567 float progress = tokens[1].toFloat(&bOK);
00568 if (!bOK)
00569 {
00570 VERBOSE(VB_IMPORTANT, "LCDServer: bad float value in "
00571 "SET_CHANNEL_PROGRESS command: %1" << tokens[1]);
00572 sendMessage(socket, "HUH?");
00573 return;
00574 }
00575
00576 if (m_lcd)
00577 m_lcd->setChannelProgress(progress);
00578
00579 sendMessage(socket, "OK");
00580 }
00581
00582 void LCDServer::setGenericProgress(const QStringList &tokens, QSocket *socket)
00583 {
00584 if (debug_level > 0)
00585 VERBOSE(VB_GENERAL, "LCDServer: SET_GENERIC_PROGRESS");
00586
00587 QString flat = tokens.join(" ");
00588
00589 if (tokens.count() != 3)
00590 {
00591 VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_GENERIC_PROGRESS command: "
00592 << flat);
00593 sendMessage(socket, "HUH?");
00594 return;
00595 }
00596
00597 bool bOK;
00598 bool busy = tokens[1].toInt(&bOK);
00599 if (!bOK)
00600 {
00601 VERBOSE(VB_IMPORTANT, "LCDServer: bad bool value in "
00602 "SET_GENERIC_PROGRESS command: %1 %2" << tokens[1] << tokens[2]);
00603 sendMessage(socket, "HUH?");
00604 return;
00605 }
00606 float progress = tokens[2].toFloat(&bOK);
00607 if (!bOK)
00608 {
00609 VERBOSE(VB_IMPORTANT, "LCDServer: bad float value in "
00610 "SET_GENERIC_PROGRESS command: %1" << tokens[1]);
00611 sendMessage(socket, "HUH?");
00612 return;
00613 }
00614
00615 if (m_lcd)
00616 m_lcd->setGenericProgress(busy, progress);
00617
00618 sendMessage(socket, "OK");
00619 }
00620
00621 void LCDServer::setMusicProgress(const QStringList &tokens, QSocket *socket)
00622 {
00623 if (debug_level > 0)
00624 VERBOSE(VB_GENERAL, "LCDServer: SET_MUSIC_PROGRESS");
00625
00626 QString flat = tokens.join(" ");
00627
00628 if (tokens.count() != 3)
00629 {
00630 VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_MUSIC_PROGRESS command: "
00631 << flat);
00632 sendMessage(socket, "HUH?");
00633 return;
00634 }
00635
00636 bool bOK;
00637 float progress = tokens[2].toFloat(&bOK);
00638 if (!bOK)
00639 {
00640 VERBOSE(VB_IMPORTANT, "LCDServer: bad float value in "
00641 "SET_MUSIC_PROGRESS command: " << tokens[2]);
00642 sendMessage(socket, "HUH?");
00643 return;
00644 }
00645
00646 if (m_lcd)
00647 m_lcd->setMusicProgress(tokens[1], progress);
00648
00649 sendMessage(socket, "OK");
00650 }
00651
00652 void LCDServer::setMusicProp(const QStringList &tokens, QSocket *socket)
00653 {
00654 if (debug_level > 0)
00655 VERBOSE(VB_GENERAL, "LCDServer: SET_MUSIC_PROP");
00656
00657 QString flat = tokens.join(" ");
00658
00659 if (tokens.count() < 3)
00660 {
00661 VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_MUSIC_PROP command: "
00662 << flat);
00663 sendMessage(socket, "HUH?");
00664 return;
00665 }
00666
00667 if (tokens[1] == "SHUFFLE")
00668 {
00669 if (tokens.count () != 3)
00670 {
00671 VERBOSE(VB_IMPORTANT, "LCDServer: missing argument for "
00672 "SET_MUSIC_PROP SHUFFLE command: " << flat);
00673 sendMessage(socket, "HUH?");
00674 return;
00675 }
00676 bool bOk;
00677 int state = tokens[2].toInt (&bOk);
00678 if (!bOk)
00679 {
00680 VERBOSE(VB_IMPORTANT, "LCDServer: bad argument for "
00681 "SET_MUSIC_PROP SHUFFLE command: " << tokens[2]);
00682 sendMessage(socket, "HUH?");
00683 return;
00684 }
00685 if (m_lcd)
00686 m_lcd->setMusicShuffle (state);
00687 }
00688 else if (tokens[1] == "REPEAT")
00689 {
00690 if (tokens.count () != 3)
00691 {
00692 VERBOSE(VB_IMPORTANT, "LCDServer: missing argument for "
00693 "SET_MUSIC_PROP REPEAT command: " << flat);
00694 sendMessage(socket, "HUH?");
00695 return;
00696 }
00697 bool bOk;
00698 int state = tokens[2].toInt (&bOk);
00699 if (!bOk)
00700 {
00701 VERBOSE(VB_IMPORTANT, "LCDServer: bad argument for "
00702 "SET_MUSIC_PROP REPEAT command: " << tokens[2]);
00703 sendMessage(socket, "HUH?");
00704 return;
00705 }
00706 if (m_lcd)
00707 m_lcd->setMusicRepeat (state);
00708 }
00709 else
00710 {
00711 VERBOSE(VB_IMPORTANT, "LCDServer: bad argument for "
00712 "SET_MUSIC_PROP command: " << tokens[1]);
00713 sendMessage(socket, "HUH?");
00714 return;
00715 }
00716
00717 sendMessage(socket, "OK");
00718 }
00719
00720 void LCDServer::setVolumeLevel(const QStringList &tokens, QSocket *socket)
00721 {
00722 if (debug_level > 0)
00723 VERBOSE(VB_GENERAL, "LCDServer: SET_VOLUME_LEVEL");
00724
00725 QString flat = tokens.join(" ");
00726
00727 if (tokens.count() != 2)
00728 {
00729 VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_VOLUME_LEVEL command: "
00730 << flat);
00731 sendMessage(socket, "HUH?");
00732 return;
00733 }
00734
00735 bool bOK;
00736 float progress = tokens[1].toFloat(&bOK);
00737 if (!bOK)
00738 {
00739 VERBOSE(VB_IMPORTANT, "LCDServer: bad float value in "
00740 "SET_VOLUME_LEVEL command: " << tokens[1]);
00741 sendMessage(socket, "HUH?");
00742 return;
00743 }
00744
00745 if (m_lcd)
00746 m_lcd->setVolumeLevel(progress);
00747
00748 sendMessage(socket, "OK");
00749 }
00750
00751 void LCDServer::updateLEDs(const QStringList &tokens, QSocket *socket)
00752 {
00753 if (debug_level > 0)
00754 VERBOSE(VB_GENERAL, "LCDServer: UPDATE_LEDS");
00755
00756 QString flat = tokens.join(" ");
00757
00758 if (tokens.count() != 2)
00759 {
00760 VERBOSE(VB_IMPORTANT, "LCDServer: bad UPDATE_LEDs command: " << flat);
00761 sendMessage(socket, "HUH?");
00762 return;
00763 }
00764
00765 bool bOK;
00766 int mask = tokens[1].toInt(&bOK);
00767 if (!bOK)
00768 {
00769 VERBOSE(VB_IMPORTANT, "LCDServer: bad mask in UPDATE_LEDS "
00770 "command: " << tokens[1]);
00771 sendMessage(socket, "HUH?");
00772 return;
00773 }
00774
00775 if (m_lcd)
00776 m_lcd->updateLEDs(mask);
00777
00778 sendMessage(socket, "OK");
00779 }