• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

kremotecontrol

  • sources
  • kde-4.12
  • kdeutils
  • kremotecontrol
  • libkremotecontrol
  • backends
  • lirc
lircclient.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright : (C) 2002 by Gav Wood <gav@kde.org> *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License or (at your option) version 3 or any later version *
8  * accepted by the membership of KDE e.V. (or its successor approved *
9  * by the membership of KDE e.V.), which shall act as a proxy *
10  * defined in Section 14 of version 3 of the license. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  *************************************************************************/
20 
21 
27 #include "lircclient.h"
28 
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <cstring>
32 #include <sys/un.h>
33 #include <sys/socket.h>
34 #include <errno.h>
35 
36 // #include <QWidget>
37 
38 #include <QObject>
39 #include <QLocalSocket>
40 #include <QFile>
41 
42 #include <kdebug.h>
43 #include <kglobal.h>
44 
45 class LircClientPrivate
46 {
47 public:
48  LircClient instance;
49 };
50 
51 K_GLOBAL_STATIC(LircClientPrivate, theInstancePrivate)
52 
53 LircClient::LircClient() : theSocket(0)
54 {
55 }
56 
57 LircClient *LircClient::self() {
58  return &theInstancePrivate->instance;
59 }
60 
61 bool LircClient::connectToLirc()
62 {
63  int sock = ::socket(PF_UNIX, SOCK_STREAM, 0);
64  if (sock == -1) return false;
65 
66  sockaddr_un addr;
67  addr.sun_family = AF_UNIX;
68  // Try to open lircd socket for lirc >= 0.8.6
69  strcpy(addr.sun_path, "/var/run/lirc/lircd");
70  if (::connect(sock, (struct sockaddr *)(&addr), sizeof(addr)) == -1) {
71  ::close(sock);
72  // for lirc < 0.8.6
73  sock = ::socket(PF_UNIX, SOCK_STREAM, 0);
74  strcpy(addr.sun_path, "/dev/lircd");
75  if (::connect(sock, (struct sockaddr *)(&addr), sizeof(addr)) == -1) {
76  ::close(sock);
77  kDebug() << "no lircd socket found...";
78  return false;
79  } else {
80  kDebug() << "lircd < 0.8.6 socket found...";
81  }
82  } else {
83  kDebug() << "lircd >= 0.8.6 socket found...";
84  }
85 
86  if(!theSocket){
87  theSocket = new QLocalSocket();
88  }
89  theSocket->setSocketDescriptor(sock);
90  kDebug() << "updating remotes";
91  updateRemotes();
92  kDebug() << "waiting for lirc";
93  theSocket->waitForReadyRead();
94  kDebug() << "reading...";
95  slotRead();
96  connect(theSocket, SIGNAL(readyRead()), SLOT(slotRead()));
97  connect(theSocket, SIGNAL(disconnected()), SLOT(slotClosed()));
98  return true;
99 }
100 
101 LircClient::~LircClient()
102 {
103  kDebug() << "deleting theSocket";
104  delete theSocket;
105 }
106 
107 void LircClient::slotClosed()
108 {
109  kDebug() << "connection closed";
110  theRemotes.clear();
111  emit connectionClosed();
112 }
113 
114 const QStringList LircClient::remotes() const
115 {
116  return theRemotes.keys();
117 }
118 
119 const QStringList LircClient::buttons(const QString &theRemote) const
120 {
121  return theRemotes.value(theRemote);
122 }
123 
124 void LircClient::slotRead()
125 {
126  while (theSocket->bytesAvailable()) {
127  QString line = readLine();
128  if (line == "BEGIN") {
129  // BEGIN
130  // <command>
131  // [SUCCESS|ERROR]
132  // [DATA
133  // n
134  // n lines of data]
135  // END
136  line = readLine();
137 kDebug() << line;
138  if (line == "SIGHUP") {
139  // Configuration changed
140  do line = readLine();
141  while (!line.isEmpty() && line != "END");
142  updateRemotes();
143  theSocket->waitForReadyRead();
144  slotRead();
145  return;
146  } else if (line == "LIST") {
147  // remote control list
148  if (readLine() != "SUCCESS" || readLine() != "DATA") {
149  do line = readLine();
150  while (!line.isEmpty() && line != "END");
151  return;
152  }
153  QStringList remotes;
154  int count = readLine().toInt();
155  for (int i = 0; i < count; ++i)
156  remotes.append(readLine());
157 kDebug() << remotes;
158  do line = readLine();
159  while (!line.isEmpty() && line != "END");
160  if (line.isEmpty())
161  return; // abort on corrupt data
162  for (QStringList::ConstIterator it = remotes.constBegin(); it != remotes.constEnd(); ++it) {
163  sendCommand("LIST " + *it);
164  theSocket->waitForReadyRead();
165  slotRead();
166  }
167  return;
168  } else if (line.left(4) == "LIST") {
169  // button list
170  if (readLine() != "SUCCESS" || readLine() != "DATA") {
171  do line = readLine();
172  while (!line.isEmpty() && line != "END");
173  return;
174  }
175  QString remote = line.mid(5);
176  QStringList buttons;
177  int count = readLine().toInt();
178  for (int i = 0; i < count; ++i) {
179  // <code> <name>
180  QString btn = readLine().mid(17);
181  if (btn.isNull()) break;
182  if (btn.startsWith('\'') && btn.endsWith('\''))
183  btn = btn.mid(1, btn.length() - 2);
184  buttons.append(btn);
185  }
186  theRemotes.insert(remote, buttons);
187  }
188  do line = readLine();
189  while (!line.isEmpty() && line != "END");
190  kDebug() << "Remotes read!";
191  emit newRemoteList(theRemotes.keys());
192  } else {
193  // <code> <repeat> <button name> <remote control name>
194  line.remove(0, 17); // strip code
195  int pos = line.indexOf(' ');
196  if (pos < 0) return;
197  bool ok;
198  int repeat = line.left(pos).toInt(&ok, 16);
199  if (!ok) return;
200  line.remove(0, pos + 1);
201 
202  pos = line.indexOf(' ');
203  if (pos < 0) return;
204  QString btn = line.left(pos);
205  if (btn.startsWith('\'') && btn.endsWith('\''))
206  btn = btn.mid(1, btn.length() - 2);
207  line.remove(0, pos + 1);
208  kDebug() << "Command received!";
209  emit commandReceived(line, btn, repeat);
210  }
211  }
212 }
213 
214 void LircClient::updateRemotes()
215 {
216  theRemotes.clear();
217  sendCommand("LIST");
218 }
219 
220 bool LircClient::isConnected() const
221 {
222  kDebug() << "theSocket" << theSocket;
223  if (!theSocket) return false;
224  kDebug() << "state:" << theSocket->state();
225  return theSocket->state() == QLocalSocket::ConnectedState;
226 }
227 
228 const QString LircClient::readLine()
229 {
230  if (!theSocket->canReadLine()) {
231  theSocket->waitForReadyRead(500);
232  if (!theSocket->canReadLine()) { // Still nothing :(
233  return QString();
234  }
235  }
236  QString line = theSocket->readLine();
237  line.truncate(line.length() - 1);
238  return line;
239 }
240 
241 void LircClient::sendCommand(const QString &command)
242 {
243  QByteArray cmd = QFile::encodeName(command + '\n');
244  theSocket->write(cmd);
245 }
246 
247 
248 #include "lircclient.moc"
LircClient::~LircClient
~LircClient()
Definition: lircclient.cpp:101
LircClient::buttons
const QStringList buttons(const QString &theRemote) const
Retrieve list of buttons of a praticular remote control.
Definition: lircclient.cpp:119
LircClient::commandReceived
void commandReceived(const QString &remote, const QString &button, int repeatCounter)
Emitted when a IR command was received.
LircClient::self
static LircClient * self()
Get the instance,.
Definition: lircclient.cpp:57
LircClient
Definition: lircclient.h:37
LircClient::connectionClosed
void connectionClosed()
Emitted when the Lirc connection is closed.
LircClient::connectToLirc
bool connectToLirc()
Connects to lirc.
Definition: lircclient.cpp:61
lircclient.h
LircClient::remotes
const QStringList remotes() const
Retrieve list of remote controls.
Definition: lircclient.cpp:114
LircClient::isConnected
bool isConnected() const
Query status of connection.
Definition: lircclient.cpp:220
LircClient::newRemoteList
void newRemoteList(const QStringList &remoteList)
Emitted when the list of controls / buttons was changed by lircd (SIGHUP)
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:07:43 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kremotecontrol

Skip menu "kremotecontrol"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal