├── .gitignore
├── AirTV-Qt
├── AirTV.icns
├── AirTV.ico
├── AirTV.pro
├── AirTV.qrc
├── AirTV.rc
├── audiocallbacks.cpp
├── audiocallbacks.h
├── audiooutput.cpp
├── audiooutput.h
├── images
│ └── airtv.svg
├── main.cpp
├── mainapplication.cpp
├── mainapplication.h
├── mainwindow.ui
└── qtsingleapplication
│ ├── INSTALL.TXT
│ ├── README.TXT
│ ├── buildlib
│ └── buildlib.pro
│ ├── common.pri
│ ├── configure
│ ├── configure.bat
│ ├── doc
│ ├── html
│ │ ├── classic.css
│ │ ├── images
│ │ │ └── qt-logo.png
│ │ ├── index.html
│ │ ├── qtsingleapplication-example-loader.html
│ │ ├── qtsingleapplication-example-trivial.html
│ │ ├── qtsingleapplication-members.html
│ │ ├── qtsingleapplication-obsolete.html
│ │ ├── qtsingleapplication.dcf
│ │ ├── qtsingleapplication.html
│ │ ├── qtsingleapplication.index
│ │ ├── qtsingleapplication.qhp
│ │ ├── qtsinglecoreapplication-example-console.html
│ │ ├── qtsinglecoreapplication-members.html
│ │ └── qtsinglecoreapplication.html
│ ├── images
│ │ └── qt-logo.png
│ └── index.qdoc
│ ├── examples
│ ├── console
│ │ ├── console.pro
│ │ ├── console.qdoc
│ │ └── main.cpp
│ ├── examples.pro
│ ├── loader
│ │ ├── file1.qsl
│ │ ├── file2.qsl
│ │ ├── loader.pro
│ │ ├── loader.qdoc
│ │ └── main.cpp
│ └── trivial
│ │ ├── main.cpp
│ │ ├── trivial.pro
│ │ └── trivial.qdoc
│ ├── qtsingleapplication.pro
│ └── src
│ ├── QtLockedFile
│ ├── QtSingleApplication
│ ├── qtlocalpeer.cpp
│ ├── qtlocalpeer.h
│ ├── qtlockedfile.cpp
│ ├── qtlockedfile.h
│ ├── qtlockedfile_unix.cpp
│ ├── qtlockedfile_win.cpp
│ ├── qtsingleapplication.cpp
│ ├── qtsingleapplication.h
│ ├── qtsingleapplication.pri
│ ├── qtsinglecoreapplication.cpp
│ ├── qtsinglecoreapplication.h
│ └── qtsinglecoreapplication.pri
├── LICENSE
├── Makefile.am
├── README.md
├── airport.key
├── autogen.sh
├── configure.ac
├── include
├── Makefile.am
└── shairplay
│ ├── dnssd.h
│ └── raop.h
├── m4
└── pkg.m4
└── src
├── Makefile.am
├── bindings
├── python
│ └── Shairplay.py
└── qt4
│ ├── dnssdservice.cpp
│ ├── dnssdservice.h
│ ├── raopcallbackhandler.cpp
│ ├── raopcallbackhandler.h
│ ├── raopcallbacks.h
│ ├── raopservice.cpp
│ └── raopservice.h
├── lib
├── Makefile.am
├── aes_ctr.c
├── aes_ctr.h
├── alac
│ ├── Makefile.am
│ ├── alac.c
│ ├── alac.h
│ └── stdint_win.h
├── base64.c
├── base64.h
├── compat.h
├── crypto
│ ├── Makefile.am
│ ├── aes.c
│ ├── bigint.c
│ ├── bigint.h
│ ├── bigint_impl.h
│ ├── config.h
│ ├── crypto.h
│ ├── hmac.c
│ ├── md5.c
│ ├── os_port.h
│ ├── rc4.c
│ └── sha1.c
├── curve25519
│ ├── Makefile.am
│ ├── curve25519-donna-c64.c
│ ├── curve25519-donna.c
│ └── curve25519.h
├── digest.c
├── digest.h
├── dnssd.c
├── dnssd.m
├── dnssdint.h
├── ed25519
│ ├── Makefile.am
│ ├── add_scalar.c
│ ├── ed25519.h
│ ├── fe.c
│ ├── fe.h
│ ├── fixedint.h
│ ├── ge.c
│ ├── ge.h
│ ├── key_exchange.c
│ ├── keypair.c
│ ├── license.txt
│ ├── precomp_data.h
│ ├── sc.c
│ ├── sc.h
│ ├── seed.c
│ ├── sha512.c
│ ├── sha512.h
│ ├── sign.c
│ └── verify.c
├── fairplay.h
├── fairplay_dummy.c
├── fairplay_playfair.c
├── global.h
├── http_parser.c
├── http_parser.h
├── http_request.c
├── http_request.h
├── http_response.c
├── http_response.h
├── httpd.c
├── httpd.h
├── logger.c
├── logger.h
├── memalign.h
├── netutils.c
├── netutils.h
├── pairing.c
├── pairing.h
├── playfair
│ ├── LICENSE.md
│ ├── Makefile.am
│ ├── hand_garble.c
│ ├── modified_md5.c
│ ├── omg_hax.c
│ ├── omg_hax.h
│ ├── playfair.c
│ ├── playfair.h
│ └── sap_hash.c
├── plist.c
├── plist.h
├── raop.c
├── raop_buffer.c
├── raop_buffer.h
├── raop_handlers.h
├── raop_rtp.c
├── raop_rtp.h
├── rsakey.c
├── rsakey.h
├── rsapem.c
├── rsapem.h
├── sdp.c
├── sdp.h
├── sockets.h
├── threads.h
├── utils.c
└── utils.h
├── shairplay.c
└── test
├── dnssd_test.c
├── dnssd_test.m
├── example.c
├── main.c
└── test.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *-build-*
2 | *.user
3 | *.o
4 | *.DS_Store
5 | *.swp
6 | project.xcworkspace
7 | xcuserdata
8 |
9 | # autotools
10 | Makefile
11 | *.lo
12 | *.in
13 | .deps
14 | .libs
15 | *.la
16 | *.a
17 | m4/
18 | missing
19 | libtool
20 | ltmain.sh
21 | install-sh
22 | depcomp
23 | configure
24 | config.*
25 | autom4te.cache
26 | aclocal.m4
27 | stamp-h1
28 | src/shairplay
29 | src/test/example
30 |
31 |
--------------------------------------------------------------------------------
/AirTV-Qt/AirTV.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juhovh/shairplay/096b61ad14c90169f438e690d096e3fcf87e504e/AirTV-Qt/AirTV.icns
--------------------------------------------------------------------------------
/AirTV-Qt/AirTV.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juhovh/shairplay/096b61ad14c90169f438e690d096e3fcf87e504e/AirTV-Qt/AirTV.ico
--------------------------------------------------------------------------------
/AirTV-Qt/AirTV.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2011-12-04T00:47:51
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui multimedia phonon svg
8 |
9 | include(qtsingleapplication/src/qtsingleapplication.pri)
10 |
11 | TARGET = AirTV
12 | TEMPLATE = app
13 | ICON = AirTV.icns
14 | RC_FILE = AirTV.rc
15 |
16 | win32 {
17 | LIBS += C:\\QtSDK\\mingw\\lib\\libws2_32.a
18 | QMAKE_LFLAGS += -static-libgcc
19 | }
20 | macx {
21 | QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5
22 | }
23 |
24 | LIBS += -lshairplay
25 | INCLUDEPATH += ../src/include/ ../src/bindings/qt4/
26 | SOURCES += main.cpp\
27 | ../src/bindings/qt4/raopservice.cpp \
28 | ../src/bindings/qt4/raopcallbackhandler.cpp \
29 | ../src/bindings/qt4/dnssdservice.cpp \
30 | audiooutput.cpp \
31 | mainapplication.cpp \
32 | audiocallbacks.cpp
33 |
34 | HEADERS += \
35 | ../src/bindings/qt4/raopservice.h \
36 | ../src/bindings/qt4/raopcallbacks.h \
37 | ../src/bindings/qt4/raopcallbackhandler.h \
38 | ../src/bindings/qt4/dnssdservice.h \
39 | audiooutput.h \
40 | mainapplication.h \
41 | audiocallbacks.h
42 |
43 | FORMS += mainwindow.ui
44 |
45 | RESOURCES += \
46 | AirTV.qrc
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/AirTV-Qt/AirTV.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/airtv.svg
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AirTV-Qt/AirTV.rc:
--------------------------------------------------------------------------------
1 | IDI_ICON1 ICON DISCARDABLE "AirTV.ico"
2 |
--------------------------------------------------------------------------------
/AirTV-Qt/audiocallbacks.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include "audiocallbacks.h"
16 |
17 | AudioCallbacks::AudioCallbacks(QObject *parent) :
18 | RaopAudioHandler(parent)
19 | {
20 | }
21 |
22 | void * AudioCallbacks::audioInit(int bits, int channels, int samplerate)
23 | {
24 | AudioOutput *audioOutput = new AudioOutput(0);
25 | audioOutput->init(bits, channels, samplerate);
26 | audioOutput->start();
27 | m_outputList.append(audioOutput);
28 | return audioOutput;
29 | }
30 |
31 | void AudioCallbacks::audioProcess(void *session, const QByteArray & buffer)
32 | {
33 | AudioOutput *audioOutput = (AudioOutput*)session;
34 | audioOutput->output(buffer);
35 | }
36 |
37 | void AudioCallbacks::audioDestroy(void *session)
38 | {
39 | AudioOutput *audioOutput = (AudioOutput*)session;
40 | m_outputList.removeAll(audioOutput);
41 |
42 | audioOutput->stop();
43 | delete audioOutput;
44 | }
45 |
46 |
47 | void AudioCallbacks::audioFlush(void *session)
48 | {
49 | AudioOutput *audioOutput = (AudioOutput*)session;
50 | audioOutput->flush();
51 | }
52 |
53 | void AudioCallbacks::audioSetVolume(void *session, float volume)
54 | {
55 | AudioOutput *audioOutput = (AudioOutput*)session;
56 | audioOutput->setVolume(volume);
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/AirTV-Qt/audiocallbacks.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef AUDIOCALLBACKS_H
16 | #define AUDIOCALLBACKS_H
17 |
18 | #include "raopcallbacks.h"
19 |
20 | #include "audiooutput.h"
21 |
22 | class AudioCallbacks : public RaopAudioHandler
23 | {
24 | Q_OBJECT
25 | public:
26 | explicit AudioCallbacks(QObject *parent = 0);
27 |
28 | virtual void *audioInit(int bits, int channels, int samplerate);
29 | virtual void audioSetVolume(void *session, float volume);
30 | virtual void audioProcess(void *session, const QByteArray &buffer);
31 | virtual void audioFlush(void *session);
32 | virtual void audioDestroy(void *session);
33 |
34 |
35 | private:
36 | QList m_outputList;
37 |
38 | signals:
39 |
40 | public slots:
41 |
42 | };
43 |
44 | #endif // AUDIOCALLBACKS_H
45 |
--------------------------------------------------------------------------------
/AirTV-Qt/audiooutput.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef AUDIOOUTPUT_H
16 | #define AUDIOOUTPUT_H
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | class AudioOutput : public QIODevice
27 | {
28 | Q_OBJECT
29 | public:
30 | explicit AudioOutput(QObject *parent = 0);
31 | bool init(int bits, int channels, int samplerate);
32 | bool setDevice(QAudioDeviceInfo deviceInfo);
33 |
34 | void start();
35 | void setVolume(float volume);
36 | void output(const QByteArray & data);
37 | void flush();
38 | void stop();
39 |
40 | qint64 readData(char *data, qint64 maxlen);
41 | qint64 writeData(const char *data, qint64 len);
42 | qint64 bytesAvailable() const;
43 | bool isSequential() const;
44 |
45 | private:
46 | void reinit();
47 |
48 | private:
49 | bool m_initialized;
50 | QByteArray m_buffer;
51 | QAudioFormat m_format;
52 | QAudioDeviceInfo m_deviceInfo;
53 | QAudioOutput* m_output;
54 | float m_volume;
55 |
56 | signals:
57 |
58 | public slots:
59 |
60 | private slots:
61 | void notified();
62 | void stateChanged(QAudio::State state);
63 | };
64 |
65 | #endif // AUDIOOUTPUT_H
66 |
--------------------------------------------------------------------------------
/AirTV-Qt/main.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include
16 | #include
17 |
18 | #include "mainapplication.h"
19 | #include "videowidget.h"
20 | #include "raopservice.h"
21 |
22 | int main(int argc, char *argv[])
23 | {
24 | QtSingleApplication a(argc, argv);
25 | if (a.isRunning()) {
26 | return 0;
27 | }
28 | a.setApplicationName("AirTV");
29 |
30 | if (!QSystemTrayIcon::isSystemTrayAvailable()) {
31 | QMessageBox::critical(0, QObject::tr("Systray"),
32 | QObject::tr("I couldn't detect any system tray "
33 | "on this system."));
34 | return 1;
35 | }
36 | QApplication::setQuitOnLastWindowClosed(false);
37 |
38 | MainApplication m;
39 | QObject::connect(&m, SIGNAL(quitRequested()), &a, SLOT(quit()));
40 | QObject::connect(&a, SIGNAL(aboutToQuit()), &m, SLOT(aboutToQuit()));
41 |
42 | if(m.start()) {
43 | return a.exec();
44 | } else {
45 | return EXIT_FAILURE;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/AirTV-Qt/mainapplication.cpp:
--------------------------------------------------------------------------------
1 | #include "mainapplication.h"
2 |
3 | #include
4 | #include
5 |
6 | MainApplication::MainApplication(QObject *parent) :
7 | QObject(parent)
8 | {
9 | raopService = new RaopService(0);
10 | dnssdService = new DnssdService(0);
11 | trayIconMenu = new QMenu(0);
12 |
13 | quitAction = new QAction(tr("&Quit"), trayIconMenu);
14 | connect(quitAction, SIGNAL(triggered()), this, SIGNAL(quitRequested()));
15 | trayIconMenu->addAction(quitAction);
16 |
17 | // Construct the actual system tray icon
18 | trayIcon = new QSystemTrayIcon(this);
19 | trayIcon->setContextMenu(trayIconMenu);
20 | trayIcon->setIcon(QIcon(":icons/airtv.svg"));
21 | }
22 |
23 | MainApplication::~MainApplication()
24 | {
25 | trayIcon->setContextMenu(0);
26 | delete trayIconMenu;
27 | delete raopService;
28 | }
29 |
30 | bool MainApplication::start()
31 | {
32 | // Initialize the service
33 | bool initSuccess = false;
34 | initSuccess = raopService->init(10, &m_callbacks);
35 | if(!initSuccess) {
36 | qDebug() << "Error initializing raop service";
37 | return false;
38 | }
39 | initSuccess &= dnssdService->init();
40 | if(!initSuccess) {
41 | qDebug() << "Error initializing dnssd service";
42 | return false;
43 | }
44 |
45 | char chwaddr[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB };
46 | QByteArray hwaddr(chwaddr, sizeof(chwaddr));
47 |
48 | raopService->start(5000, hwaddr);
49 | dnssdService->registerRaop("Shairplay", 5000, hwaddr);
50 | trayIcon->show();
51 | return true;
52 | }
53 |
54 | void MainApplication::stop()
55 | {
56 | dnssdService->unregisterRaop();
57 | raopService->stop();
58 | trayIcon->hide();
59 | }
60 |
61 | void MainApplication::aboutToQuit()
62 | {
63 | this->stop();
64 | }
65 |
--------------------------------------------------------------------------------
/AirTV-Qt/mainapplication.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef MAINAPPLICATION_H
16 | #define MAINAPPLICATION_H
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "raopservice.h"
24 | #include "dnssdservice.h"
25 | #include "audiocallbacks.h"
26 |
27 | class MainApplication : public QObject
28 | {
29 | Q_OBJECT
30 | public:
31 | explicit MainApplication(QObject *parent = 0);
32 | ~MainApplication();
33 |
34 | bool start();
35 | void stop();
36 |
37 | private:
38 | RaopService *raopService;
39 | DnssdService *dnssdService;
40 | AudioCallbacks m_callbacks;
41 |
42 | QSystemTrayIcon *trayIcon;
43 | QMenu *trayIconMenu;
44 | QAction *quitAction;
45 |
46 | signals:
47 | void quitRequested();
48 |
49 | public slots:
50 | void aboutToQuit();
51 | };
52 |
53 | #endif // MAINAPPLICATION_H
54 |
--------------------------------------------------------------------------------
/AirTV-Qt/mainwindow.ui:
--------------------------------------------------------------------------------
1 |
2 | MainWindow
3 |
4 |
5 |
6 | 0
7 | 0
8 | 400
9 | 300
10 |
11 |
12 |
13 | MainWindow
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/README.TXT:
--------------------------------------------------------------------------------
1 | Qt Solutions Component: Single Application
2 |
3 | The QtSingleApplication component provides support for
4 | applications that can be only started once per user.
5 |
6 |
7 |
8 | Version history:
9 |
10 | 2.0: - Version 1.3 ported to Qt 4.
11 |
12 | 2.1: - Fix compilation problem on Mac.
13 |
14 | 2.2: - Really fix the Mac compilation problem.
15 | - Mac: fix crash due to wrong object releasing.
16 | - Mac: Fix memory leak.
17 |
18 | 2.3: - Windows: Force creation of internal widget to make it work
19 | with Qt 4.2.
20 |
21 | 2.4: - Fix the system for automatic window raising on message
22 | reception. NOTE: minor API change.
23 |
24 | 2.5: - Mac: Fix isRunning() to work and report correctly.
25 |
26 | 2.6: - - initialize() is now obsolete, no longer necessary to call
27 | it
28 | - - Fixed race condition where multiple instances migth be started
29 | - - QtSingleCoreApplication variant provided for non-GUI (console)
30 | usage
31 | - Complete reimplementation. Visible changes:
32 | - LGPL release.
33 |
34 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/buildlib/buildlib.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE=lib
2 | CONFIG += qt dll qtsingleapplication-buildlib
3 | mac:CONFIG += absolute_library_soname
4 | win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release build_all
5 | include(../src/qtsingleapplication.pri)
6 | TARGET = $$QTSINGLEAPPLICATION_LIBNAME
7 | DESTDIR = $$QTSINGLEAPPLICATION_LIBDIR
8 | win32 {
9 | DLLDESTDIR = $$[QT_INSTALL_BINS]
10 | QMAKE_DISTCLEAN += $$[QT_INSTALL_BINS]\\$${QTSINGLEAPPLICATION_LIBNAME}.dll
11 | }
12 | target.path = $$DESTDIR
13 | INSTALLS += target
14 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/common.pri:
--------------------------------------------------------------------------------
1 | infile(config.pri, SOLUTIONS_LIBRARY, yes): CONFIG += qtsingleapplication-uselib
2 | TEMPLATE += fakelib
3 | QTSINGLEAPPLICATION_LIBNAME = $$qtLibraryTarget(QtSolutions_SingleApplication-head)
4 | TEMPLATE -= fakelib
5 | QTSINGLEAPPLICATION_LIBDIR = $$PWD/lib
6 | unix:qtsingleapplication-uselib:!qtsingleapplication-buildlib:QMAKE_RPATHDIR += $$QTSINGLEAPPLICATION_LIBDIR
7 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/configure:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ "x$1" != "x" -a "x$1" != "x-library" ]; then
4 | echo "Usage: $0 [-library]"
5 | echo
6 | echo "-library: Build the component as a dynamic library (DLL). Default is to"
7 | echo " include the component source code directly in the application."
8 | echo
9 | exit 0
10 | fi
11 |
12 | rm -f config.pri
13 | if [ "x$1" = "x-library" ]; then
14 | echo "Configuring to build this component as a dynamic library."
15 | echo "SOLUTIONS_LIBRARY = yes" > config.pri
16 | fi
17 |
18 | echo
19 | echo "This component is now configured."
20 | echo
21 | echo "To build the component library (if requested) and example(s),"
22 | echo "run qmake and your make command."
23 | echo
24 | echo "To remove or reconfigure, run make distclean."
25 | echo
26 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/configure.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem
4 | rem "Main"
5 | rem
6 |
7 | if not "%1"=="" (
8 | if not "%1"=="-library" (
9 | call :PrintUsage
10 | goto EOF
11 | )
12 | )
13 |
14 | if exist config.pri. del config.pri
15 | if "%1"=="-library" (
16 | echo Configuring to build this component as a dynamic library.
17 | echo SOLUTIONS_LIBRARY = yes > config.pri
18 | )
19 |
20 | echo .
21 | echo This component is now configured.
22 | echo .
23 | echo To build the component library (if requested) and example(s),
24 | echo run qmake and your make or nmake command.
25 | echo .
26 | echo To remove or reconfigure, run make (nmake) distclean.
27 | echo .
28 |
29 | :PrintUsage
30 | echo Usage: configure.bat [-library]
31 | echo .
32 | echo -library: Build the component as a dynamic library (DLL). Default is to
33 | echo include the component source directly in the application.
34 | echo A DLL may be preferable for technical or licensing (LGPL) reasons.
35 | echo .
36 | goto EOF
37 |
38 |
39 | :EOF
40 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/doc/html/images/qt-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juhovh/shairplay/096b61ad14c90169f438e690d096e3fcf87e504e/AirTV-Qt/qtsingleapplication/doc/html/images/qt-logo.png
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/doc/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | Single Application
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Single Application
16 |
17 |
18 | Description
19 | The QtSingleApplication component provides support for applications that can be only started once per user.
20 | For some applications it is useful or even critical that they are started only once by any user. Future attempts to start the application should activate any already running instance, and possibly perform requested actions, e.g. loading a file, in that instance.
21 | The QtSingleApplication class provides an interface to detect a running instance, and to send command strings to that instance. For console (non-GUI) applications, the QtSingleCoreApplication variant is provided, which avoids dependency on QtGui .
22 |
23 | Classes
24 |
28 |
29 | Examples
30 |
35 |
36 | Tested platforms
37 |
38 | Qt 4.4, 4.5 / Windows XP / MSVC.NET 2005
39 | Qt 4.4, 4.5 / Linux / gcc
40 | Qt 4.4, 4.5 / MacOS X 10.5 / gcc
41 |
42 |
43 |
44 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
45 | Trademarks
46 | Qt Solutions
47 |
48 |
49 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/doc/html/qtsingleapplication-obsolete.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | Obsolete Members for QtSingleApplication
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Obsolete Members for QtSingleApplication
16 | The following class members are obsolete. They are provided to keep old source code working. We strongly advise against using them in new code.
17 |
18 | Public Functions
19 |
20 | void initialize ( bool dummy = true ) (obsolete)
21 |
22 |
23 | Member Function Documentation
24 | void QtSingleApplication::initialize ( bool dummy = true )
25 |
26 |
27 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
28 | Trademarks
29 | Qt Solutions
30 |
31 |
32 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/doc/html/qtsingleapplication.dcf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | QtSingleApplication
6 | activateWindow
7 | activationWindow
8 | id
9 | isRunning
10 | messageReceived
11 | sendMessage
12 | setActivationWindow
13 |
14 |
15 |
16 |
17 | QtSingleCoreApplication
18 | id
19 | isRunning
20 | messageReceived
21 | sendMessage
22 |
23 |
24 |
25 |
26 |
27 | A non-GUI example
28 |
29 |
30 | A Trivial Example
31 |
32 |
33 | Loading Documents
34 |
35 |
36 | Single Application
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/doc/html/qtsingleapplication.qhp:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.nokia.qtsolutions.qtsingleapplication_head
4 | qdoc
5 |
6 | qt
7 | solutions
8 | qtsingleapplication
9 |
10 |
11 | qt
12 | solutions
13 | qtsingleapplication
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | qtsingleapplication.html
44 | index.html
45 | qtsingleapplication-example-trivial.html
46 | qtsinglecoreapplication.html
47 | qtsingleapplication-example-loader.html
48 | qtsinglecoreapplication-example-console.html
49 | classic.css
50 | images/qt-logo.png
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/doc/images/qt-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juhovh/shairplay/096b61ad14c90169f438e690d096e3fcf87e504e/AirTV-Qt/qtsingleapplication/doc/images/qt-logo.png
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/doc/index.qdoc:
--------------------------------------------------------------------------------
1 | /*!
2 | \page index.html
3 | \title Single Application
4 |
5 | \section1 Description
6 |
7 | The QtSingleApplication component provides support
8 | for applications that can be only started once per user.
9 |
10 |
11 |
12 | For some applications it is useful or even critical that they are started
13 | only once by any user. Future attempts to start the application should
14 | activate any already running instance, and possibly perform requested
15 | actions, e.g. loading a file, in that instance.
16 |
17 | The QtSingleApplication class provides an interface to detect a running
18 | instance, and to send command strings to that instance.
19 | For console (non-GUI) applications, the QtSingleCoreApplication variant is provided, which avoids dependency on QtGui.
20 |
21 |
22 |
23 |
24 | \section1 Classes
25 | \list
26 | \i QtSingleApplication \i QtSingleCoreApplication\endlist
27 |
28 | \section1 Examples
29 | \list
30 | \i \link qtsingleapplication-example-trivial.html A Trivial Example \endlink \i \link qtsingleapplication-example-loader.html Loading Documents \endlink \i \link qtsinglecoreapplication-example-console.html A Non-GUI Example \endlink \endlist
31 |
32 |
33 |
34 |
35 |
36 |
37 | \section1 Tested platforms
38 | \list
39 | \i Qt 4.4, 4.5 / Windows XP / MSVC.NET 2005
40 | \i Qt 4.4, 4.5 / Linux / gcc
41 | \i Qt 4.4, 4.5 / MacOS X 10.5 / gcc
42 | \endlist
43 |
44 |
45 |
46 |
47 | */
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/console/console.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 | CONFIG += console
3 | SOURCES += main.cpp
4 | include(../../src/qtsinglecoreapplication.pri)
5 | QT -= gui
6 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/console/console.qdoc:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | /*! \page qtsinglecoreapplication-example-console.html
41 | \title A non-GUI example
42 |
43 | This example shows how to use the single-application functionality
44 | in a console application. It does not require the \c QtGui library
45 | at all.
46 |
47 | The only differences from the GUI application usage demonstrated
48 | in the other examples are:
49 |
50 | 1) The \c.pro file should include \c qtsinglecoreapplication.pri
51 | instead of \c qtsingleapplication.pri
52 |
53 | 2) The class name is \c QtSingleCoreApplication instead of \c
54 | QtSingleApplication.
55 |
56 | 3) No calls are made regarding window activation, for obvious reasons.
57 |
58 | console.pro:
59 | \quotefile console/console.pro
60 |
61 | main.cpp:
62 | \quotefile console/main.cpp
63 |
64 | */
65 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/console/main.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 |
41 | #include "qtsinglecoreapplication.h"
42 | #include
43 |
44 |
45 | void report(const QString& msg)
46 | {
47 | qDebug("[%i] %s", (int)QCoreApplication::applicationPid(), qPrintable(msg));
48 | }
49 |
50 | class MainClass : public QObject
51 | {
52 | Q_OBJECT
53 | public:
54 | MainClass()
55 | : QObject()
56 | {}
57 |
58 | public slots:
59 | void handleMessage(const QString& message)
60 | {
61 | report( "Message received: \"" + message + "\"");
62 | }
63 | };
64 |
65 | int main(int argc, char **argv)
66 | {
67 | report("Starting up");
68 |
69 | QtSingleCoreApplication app(argc, argv);
70 |
71 | if (app.isRunning()) {
72 | QString msg(QString("Hi master, I am %1.").arg(QCoreApplication::applicationPid()));
73 | bool sentok = app.sendMessage(msg, 2000);
74 | QString rep("Another instance is running, so I will exit.");
75 | rep += sentok ? " Message sent ok." : " Message sending failed; the other instance may be frozen.";
76 | report(rep);
77 | return 0;
78 | } else {
79 | report("No other instance is running; so I will.");
80 | MainClass mainObj;
81 | QObject::connect(&app, SIGNAL(messageReceived(const QString&)),
82 | &mainObj, SLOT(handleMessage(const QString&)));
83 | return app.exec();
84 | }
85 | }
86 |
87 |
88 | #include "main.moc"
89 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/examples.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = subdirs
2 | SUBDIRS = trivial \
3 | loader \
4 | console
5 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/loader/file1.qsl:
--------------------------------------------------------------------------------
1 | File 1
2 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/loader/file2.qsl:
--------------------------------------------------------------------------------
1 | File 2
2 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/loader/loader.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 |
3 | include(../../src/qtsingleapplication.pri)
4 |
5 | SOURCES += main.cpp
6 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/loader/loader.qdoc:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | /*! \page qtsingleapplication-example-loader.html
41 | \title Loading Documents
42 |
43 | The application in this example loads or prints the documents
44 | passed as commandline parameters to further instances of this
45 | application.
46 |
47 | \quotefromfile loader/main.cpp
48 | \printuntil };
49 | The user interface in this application is a QMainWindow subclass
50 | with a QMdiArea as the central widget. It implements a slot
51 | \c handleMessage() that will be connected to the messageReceived()
52 | signal of the QtSingleApplication class.
53 |
54 | \printuntil }
55 | The MainWindow constructor creates a minimal user interface.
56 |
57 | \printto case Print:
58 | The handleMessage() slot interprets the message passed in as a
59 | filename that can be prepended with \e /print to indicate that
60 | the file should just be printed rather than loaded.
61 |
62 | \printto #include
63 | Loading the file will also activate the window.
64 |
65 | \printto mw
66 | The \c main entry point function creates a QtSingleApplication
67 | object, and creates a message to send to a running instance
68 | of the application. If the message was sent successfully the
69 | process exits immediately.
70 |
71 | \printuntil }
72 | If the message could not be sent the application starts up. Note
73 | that \c false is passed to the call to setActivationWindow() to
74 | prevent automatic activation for every message received, e.g. when
75 | the application should just print a file. Instead, the message
76 | handling function determines whether activation is requested, and
77 | signals that by emitting the needToShow() signal. This is then
78 | simply connected directly to QtSingleApplication's
79 | activateWindow() slot.
80 | */
81 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/loader/main.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 |
49 | class MainWindow : public QMainWindow
50 | {
51 | Q_OBJECT
52 | public:
53 | MainWindow();
54 |
55 | public slots:
56 | void handleMessage(const QString& message);
57 |
58 | signals:
59 | void needToShow();
60 |
61 | private:
62 | QMdiArea *workspace;
63 | };
64 |
65 | MainWindow::MainWindow()
66 | {
67 | workspace = new QMdiArea(this);
68 |
69 | setCentralWidget(workspace);
70 | }
71 |
72 | void MainWindow::handleMessage(const QString& message)
73 | {
74 | enum Action {
75 | Nothing,
76 | Open,
77 | Print
78 | } action;
79 |
80 | action = Nothing;
81 | QString filename = message;
82 | if (message.toLower().startsWith("/print ")) {
83 | filename = filename.mid(7);
84 | action = Print;
85 | } else if (!message.isEmpty()) {
86 | action = Open;
87 | }
88 | if (action == Nothing) {
89 | emit needToShow();
90 | return;
91 | }
92 |
93 | QFile file(filename);
94 | QString contents;
95 | if (file.open(QIODevice::ReadOnly))
96 | contents = file.readAll();
97 | else
98 | contents = "[[Error: Could not load file " + filename + "]]";
99 |
100 | QTextEdit *view = new QTextEdit;
101 | view->setPlainText(contents);
102 |
103 | switch(action) {
104 | case Print:
105 | {
106 | QPrinter printer;
107 | view->print(&printer);
108 | delete view;
109 | }
110 | break;
111 |
112 | case Open:
113 | {
114 | workspace->addSubWindow(view);
115 | view->setWindowTitle(message);
116 | view->show();
117 | emit needToShow();
118 | }
119 | break;
120 | default:
121 | break;
122 | };
123 | }
124 |
125 | #include "main.moc"
126 |
127 | int main(int argc, char **argv)
128 | {
129 | QtSingleApplication instance("File loader QtSingleApplication example", argc, argv);
130 | QString message;
131 | for (int a = 1; a < argc; ++a) {
132 | message += argv[a];
133 | if (a < argc-1)
134 | message += " ";
135 | }
136 |
137 | if (instance.sendMessage(message))
138 | return 0;
139 |
140 | MainWindow mw;
141 | mw.handleMessage(message);
142 | mw.show();
143 |
144 | QObject::connect(&instance, SIGNAL(messageReceived(const QString&)),
145 | &mw, SLOT(handleMessage(const QString&)));
146 |
147 | instance.setActivationWindow(&mw, false);
148 | QObject::connect(&mw, SIGNAL(needToShow()), &instance, SLOT(activateWindow()));
149 |
150 | return instance.exec();
151 | }
152 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/trivial/main.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | #include
41 | #include
42 |
43 | class TextEdit : public QTextEdit
44 | {
45 | Q_OBJECT
46 | public:
47 | TextEdit(QWidget *parent = 0)
48 | : QTextEdit(parent)
49 | {}
50 | public slots:
51 | void append(const QString &str)
52 | {
53 | QTextEdit::append(str);
54 | }
55 | };
56 |
57 | #include "main.moc"
58 |
59 |
60 |
61 | int main(int argc, char **argv)
62 | {
63 | QtSingleApplication instance(argc, argv);
64 | if (instance.sendMessage("Wake up!"))
65 | return 0;
66 |
67 | TextEdit logview;
68 | logview.setReadOnly(true);
69 | logview.show();
70 |
71 | instance.setActivationWindow(&logview);
72 |
73 | QObject::connect(&instance, SIGNAL(messageReceived(const QString&)),
74 | &logview, SLOT(append(const QString&)));
75 |
76 | return instance.exec();
77 | }
78 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/trivial/trivial.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 |
3 | include(../../src/qtsingleapplication.pri)
4 |
5 | SOURCES += main.cpp
6 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/examples/trivial/trivial.qdoc:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | /*! \page qtsingleapplication-example-trivial.html
41 | \title A Trivial Example
42 |
43 | The application in this example has a log-view that displays
44 | messages sent by further instances of the same application.
45 |
46 | The example demonstrates the use of the QtSingleApplication
47 | class to detect and communicate with a running instance of
48 | the application using the sendMessage() API. The messageReceived()
49 | signal is used to display received messages in a QTextEdit log.
50 |
51 | \quotefromfile trivial/main.cpp
52 | \printuntil instance
53 | The example has only the \c main entry point function.
54 | A QtSingleApplication object is created immediately.
55 |
56 | \printuntil return
57 | If another instance of this application is already running,
58 | sendMessage() will succeed, and this instance just exits
59 | immediately.
60 |
61 | \printuntil show()
62 | Otherwise the instance continues as normal and creates the
63 | user interface.
64 |
65 | \printuntil return instance.exec();
66 | The \c logview object is also set as the application's activation
67 | window. Every time a message is received, the window will be raised
68 | and activated automatically.
69 |
70 | The messageReceived() signal is also connected to the QTextEdit's
71 | append() slot. Every message received from further instances of
72 | this application will be displayed in the log.
73 |
74 | Finally the event loop is entered.
75 | */
76 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/qtsingleapplication.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE=subdirs
2 | CONFIG += ordered
3 | include(common.pri)
4 | qtsingleapplication-uselib:SUBDIRS=buildlib
5 | SUBDIRS+=examples
6 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/QtLockedFile:
--------------------------------------------------------------------------------
1 | #include "qtlockedfile.h"
2 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/QtSingleApplication:
--------------------------------------------------------------------------------
1 | #include "qtsingleapplication.h"
2 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/qtlocalpeer.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | #ifndef QTLOCALPEER_H
41 | #define QTLOCALPEER_H
42 |
43 | #include
44 | #include
45 | #include
46 |
47 | #include "qtlockedfile.h"
48 |
49 | class QtLocalPeer : public QObject
50 | {
51 | Q_OBJECT
52 |
53 | public:
54 | QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
55 | bool isClient();
56 | bool sendMessage(const QString &message, int timeout);
57 | QString applicationId() const
58 | { return id; }
59 |
60 | Q_SIGNALS:
61 | void messageReceived(const QString &message);
62 |
63 | protected Q_SLOTS:
64 | void receiveConnection();
65 |
66 | protected:
67 | QString id;
68 | QString socketName;
69 | QLocalServer* server;
70 | QtLP_Private::QtLockedFile lockFile;
71 |
72 | private:
73 | static const char* ack;
74 | };
75 |
76 | #endif // QTLOCALPEER_H
77 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/qtlockedfile.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | #ifndef QTLOCKEDFILE_H
41 | #define QTLOCKEDFILE_H
42 |
43 | #include
44 | #ifdef Q_OS_WIN
45 | #include
46 | #endif
47 |
48 | #if defined(Q_WS_WIN)
49 | # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
50 | # define QT_QTLOCKEDFILE_EXPORT
51 | # elif defined(QT_QTLOCKEDFILE_IMPORT)
52 | # if defined(QT_QTLOCKEDFILE_EXPORT)
53 | # undef QT_QTLOCKEDFILE_EXPORT
54 | # endif
55 | # define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
56 | # elif defined(QT_QTLOCKEDFILE_EXPORT)
57 | # undef QT_QTLOCKEDFILE_EXPORT
58 | # define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
59 | # endif
60 | #else
61 | # define QT_QTLOCKEDFILE_EXPORT
62 | #endif
63 |
64 | namespace QtLP_Private {
65 |
66 | class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
67 | {
68 | public:
69 | enum LockMode { NoLock = 0, ReadLock, WriteLock };
70 |
71 | QtLockedFile();
72 | QtLockedFile(const QString &name);
73 | ~QtLockedFile();
74 |
75 | bool open(OpenMode mode);
76 |
77 | bool lock(LockMode mode, bool block = true);
78 | bool unlock();
79 | bool isLocked() const;
80 | LockMode lockMode() const;
81 |
82 | private:
83 | #ifdef Q_OS_WIN
84 | Qt::HANDLE wmutex;
85 | Qt::HANDLE rmutex;
86 | QVector rmutexes;
87 | QString mutexname;
88 |
89 | Qt::HANDLE getMutexHandle(int idx, bool doCreate);
90 | bool waitMutex(Qt::HANDLE mutex, bool doBlock);
91 |
92 | #endif
93 | LockMode m_lock_mode;
94 | };
95 | }
96 | #endif
97 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/qtlockedfile_unix.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | #include "qtlockedfile.h"
46 |
47 | bool QtLockedFile::lock(LockMode mode, bool block)
48 | {
49 | if (!isOpen()) {
50 | qWarning("QtLockedFile::lock(): file is not opened");
51 | return false;
52 | }
53 |
54 | if (mode == NoLock)
55 | return unlock();
56 |
57 | if (mode == m_lock_mode)
58 | return true;
59 |
60 | if (m_lock_mode != NoLock)
61 | unlock();
62 |
63 | struct flock fl;
64 | fl.l_whence = SEEK_SET;
65 | fl.l_start = 0;
66 | fl.l_len = 0;
67 | fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
68 | int cmd = block ? F_SETLKW : F_SETLK;
69 | int ret = fcntl(handle(), cmd, &fl);
70 |
71 | if (ret == -1) {
72 | if (errno != EINTR && errno != EAGAIN)
73 | qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
74 | return false;
75 | }
76 |
77 |
78 | m_lock_mode = mode;
79 | return true;
80 | }
81 |
82 |
83 | bool QtLockedFile::unlock()
84 | {
85 | if (!isOpen()) {
86 | qWarning("QtLockedFile::unlock(): file is not opened");
87 | return false;
88 | }
89 |
90 | if (!isLocked())
91 | return true;
92 |
93 | struct flock fl;
94 | fl.l_whence = SEEK_SET;
95 | fl.l_start = 0;
96 | fl.l_len = 0;
97 | fl.l_type = F_UNLCK;
98 | int ret = fcntl(handle(), F_SETLKW, &fl);
99 |
100 | if (ret == -1) {
101 | qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
102 | return false;
103 | }
104 |
105 | m_lock_mode = NoLock;
106 | return true;
107 | }
108 |
109 | QtLockedFile::~QtLockedFile()
110 | {
111 | if (isOpen())
112 | unlock();
113 | }
114 |
115 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/qtsingleapplication.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | #ifndef QTSINGLEAPPLICATION_H
41 | #define QTSINGLEAPPLICATION_H
42 |
43 | #include
44 |
45 | class QtLocalPeer;
46 |
47 | #if defined(Q_WS_WIN)
48 | # if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT)
49 | # define QT_QTSINGLEAPPLICATION_EXPORT
50 | # elif defined(QT_QTSINGLEAPPLICATION_IMPORT)
51 | # if defined(QT_QTSINGLEAPPLICATION_EXPORT)
52 | # undef QT_QTSINGLEAPPLICATION_EXPORT
53 | # endif
54 | # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport)
55 | # elif defined(QT_QTSINGLEAPPLICATION_EXPORT)
56 | # undef QT_QTSINGLEAPPLICATION_EXPORT
57 | # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport)
58 | # endif
59 | #else
60 | # define QT_QTSINGLEAPPLICATION_EXPORT
61 | #endif
62 |
63 | class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication
64 | {
65 | Q_OBJECT
66 |
67 | public:
68 | QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
69 | QtSingleApplication(const QString &id, int &argc, char **argv);
70 | QtSingleApplication(int &argc, char **argv, Type type);
71 | #if defined(Q_WS_X11)
72 | QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
73 | QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
74 | QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
75 | #endif
76 |
77 | bool isRunning();
78 | QString id() const;
79 |
80 | void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
81 | QWidget* activationWindow() const;
82 |
83 | // Obsolete:
84 | void initialize(bool dummy = true)
85 | { isRunning(); Q_UNUSED(dummy) }
86 |
87 | public Q_SLOTS:
88 | bool sendMessage(const QString &message, int timeout = 5000);
89 | void activateWindow();
90 |
91 |
92 | Q_SIGNALS:
93 | void messageReceived(const QString &message);
94 |
95 |
96 | private:
97 | void sysInit(const QString &appId = QString());
98 | QtLocalPeer *peer;
99 | QWidget *actWin;
100 | };
101 |
102 | #endif // QTSINGLEAPPLICATION_H
103 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/qtsingleapplication.pri:
--------------------------------------------------------------------------------
1 | include(../common.pri)
2 | INCLUDEPATH += $$PWD
3 | DEPENDPATH += $$PWD
4 | QT *= network
5 |
6 | qtsingleapplication-uselib:!qtsingleapplication-buildlib {
7 | LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME
8 | } else {
9 | SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp
10 | HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h
11 | }
12 |
13 | win32 {
14 | contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT
15 | else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT
16 | }
17 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/qtsinglecoreapplication.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 | ** All rights reserved.
5 | **
6 | ** Contact: Nokia Corporation (qt-info@nokia.com)
7 | **
8 | ** This file is part of a Qt Solutions component.
9 | **
10 | ** You may use this file under the terms of the BSD license as follows:
11 | **
12 | ** "Redistribution and use in source and binary forms, with or without
13 | ** modification, are permitted provided that the following conditions are
14 | ** met:
15 | ** * Redistributions of source code must retain the above copyright
16 | ** notice, this list of conditions and the following disclaimer.
17 | ** * Redistributions in binary form must reproduce the above copyright
18 | ** notice, this list of conditions and the following disclaimer in
19 | ** the documentation and/or other materials provided with the
20 | ** distribution.
21 | ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 | ** the names of its contributors may be used to endorse or promote
23 | ** products derived from this software without specific prior written
24 | ** permission.
25 | **
26 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 | **
38 | ****************************************************************************/
39 |
40 | #ifndef QTSINGLECOREAPPLICATION_H
41 | #define QTSINGLECOREAPPLICATION_H
42 |
43 | #include
44 |
45 | class QtLocalPeer;
46 |
47 | class QtSingleCoreApplication : public QCoreApplication
48 | {
49 | Q_OBJECT
50 |
51 | public:
52 | QtSingleCoreApplication(int &argc, char **argv);
53 | QtSingleCoreApplication(const QString &id, int &argc, char **argv);
54 |
55 | bool isRunning();
56 | QString id() const;
57 |
58 | public Q_SLOTS:
59 | bool sendMessage(const QString &message, int timeout = 5000);
60 |
61 |
62 | Q_SIGNALS:
63 | void messageReceived(const QString &message);
64 |
65 |
66 | private:
67 | QtLocalPeer* peer;
68 | };
69 |
70 | #endif // QTSINGLECOREAPPLICATION_H
71 |
--------------------------------------------------------------------------------
/AirTV-Qt/qtsingleapplication/src/qtsinglecoreapplication.pri:
--------------------------------------------------------------------------------
1 | INCLUDEPATH += $$PWD
2 | DEPENDPATH += $$PWD
3 | HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h
4 | SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp
5 |
6 | QT *= network
7 |
8 | win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
9 | DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport)
10 | }
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Following licenses apply:
2 |
3 | src/lib/alac/* - MIT License
4 | src/lib/crypto/* - New BSD License
5 | src/lib/http_parser.* - MIT License
6 | src/lib/* - LGPLv2.1+ License
7 | src/bindings/* - MIT License
8 | src/* - MIT License
9 | AirTV-Qt/* - LGPLv2.1+ License
10 |
11 | Also the following files are used, although not necessary:
12 |
13 | AirTV-Qt/qtsingleapplication/src/* - New BSD License
14 |
15 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | SUBDIRS = include src
2 |
3 | ACLOCAL_AMFLAGS = -I m4
4 |
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Shairplay
2 | =========
3 | Free portable AirPlay server implementation similar to [ShairPort](https://github.com/abrasive/shairport).
4 |
5 | Currently only AirPort Express emulation is supported.
6 |
7 | Disclaimer
8 | ----------
9 | All the resources in this repository are written using only freely available
10 | information from the internet. The code and related resources are meant for
11 | educational purposes only. It is the responsibility of the user to make sure
12 | all local laws are adhered to.
13 |
14 | Installation
15 | ------------
16 |
17 | First you need to install some dependencies, for example on Ubuntu you would
18 | write:
19 | ```
20 | sudo apt-get install autoconf automake libtool
21 | sudo apt-get install libltdl-dev libao-dev libavahi-compat-libdnssd-dev
22 | sudo apt-get install avahi-daemon
23 | ```
24 |
25 | ```
26 | ./autogen.sh
27 | ./configure
28 | make
29 | sudo make install
30 | ```
31 |
32 | Notice that libao is required in order to install the shairplay binary,
33 | otherwise only the library is compiled and installed.
34 |
35 | ### Fairplay handshake support
36 |
37 | The library has experimental support for handling fairplay handshake (used in
38 | for example screen mirroring) using a playfair library that is licensed under
39 | GPLv3. This can be enabled by adding ```--with-playfair``` to the
40 | ```./configure``` command above.
41 |
42 | Usage
43 | -----
44 |
45 | Check available options with ```shairplay --help```:
46 |
47 | ```
48 | Usage: shairplay [OPTION...]
49 |
50 | -a, --apname=AirPort Sets Airport name
51 | -p, --password=secret Sets password
52 | -o, --server_port=5000 Sets port for RAOP service
53 | --ao_driver=driver Sets the ao driver (optional)
54 | --hwaddr=address Sets the MAC address, useful if running multuple instances
55 | --ao_devicename=devicename Sets the ao device name (optional)
56 | --ao_deviceid=id Sets the ao device id (optional)
57 | -h, --help This help
58 | ```
59 |
60 | Start the server with ```shairplay```, if you are connected to a Wi-Fi the
61 | server should show as an AirPort Express on your iOS devices and Mac OS X
62 | computers in the same network.
63 |
64 | Notice that you need to have the airport.key file in your working directory when
65 | starting the shairplay service. It is not included in the binary for possible
66 | legal reasons.
67 |
68 | Multiple Instances
69 | ------------------
70 |
71 | Shairplay advertises over mDNS in the form 485D607CEE22@Dining Room Speakers where 485D607CEE22 is a MAC address. This is hardcoded to a nonsense value, which is not a problem so long as it's unique. However, if you run multiple Shairplay instances, iOS devices will only recognize one of them. To fix this, supply the --hwaddr option with different values on each device.
72 |
73 | Related software
74 | ----------------
75 |
76 | * [ShairPort](https://github.com/abrasive/shairport), original AirPort Express emulator
77 | * [ALAC](http://craz.net/programs/itunes/alac.html), ALAC decoder by David Hammerton
78 |
79 | Description
80 | -----------
81 |
82 | Short description about what each file in the main library does:
83 |
84 | ```
85 | src/lib/base64.* - base64 encoder/decoder
86 | src/lib/dnssd.* - dnssd helper functions
87 | src/lib/http_parser.* - HTTP parser from joyent (nginx fork)
88 | src/lib/http_request.* - Request parser that uses http_parser
89 | src/lib/http_response.* - Extremely simple HTTP response serializer
90 | src/lib/httpd.* - Generic HTTP/RTSP server
91 | src/lib/logger.* - Logging related functions
92 | src/lib/netutils.* - Mostly socket related code
93 | src/lib/raop.* - Main RAOP handler, handles all RTSP stuff
94 | src/lib/raop_rtp.* - Handles the RAOP RTP related stuff (UDP/TCP)
95 | src/lib/raop_buffer.* - Parses and buffers RAOP packets, resend logic here
96 | src/lib/rsakey.* - Decrypts and parses the RSA key to bigints
97 | src/lib/rsapem.* - Converts the RSA PEM key to DER encoded bytes
98 | src/lib/sdp.* - Extremely simple RAOP specific SDP parser
99 | src/lib/utils.* - Utils for reading a file and handling strings
100 | ```
101 |
102 | Short description about what each file in the Qt application does:
103 |
104 | ```
105 | AirTV-Qt/main.cpp - Initializes the application
106 | AirTV-Qt/mainapplication.cpp - Creates the tray icon and starts RAOP
107 | AirTV-Qt/raopservice.cpp - Handles all communication with the library
108 | AirTV-Qt/raopcallbackhandler.cpp - Converts C callbacks to Qt callbacks
109 | AirTV-Qt/audiooutput.cpp - Takes care of the actual audio output
110 | ```
111 |
112 |
--------------------------------------------------------------------------------
/airport.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpQIBAAKCAQEA59dE8qLieItsH1WgjrcFRKj6eUWqi+bGLOX1HL3U3GhC/j0Qg90u3sG/1CUt
3 | wC5vOYvfDmFI6oSFXi5ELabWJmT2dKHzBJKa3k9ok+8t9ucRqMd6DZHJ2YCCLlDRKSKv6kDqnw4U
4 | wPdpOMXziC/AMj3Z/lUVX1G7WSHCAWKf1zNS1eLvqr+boEjXuBOitnZ/bDzPHrTOZz0Dew0uowxf
5 | /+sG+NCK3eQJVxqcaJ/vEHKIVd2M+5qL71yJQ+87X6oV3eaYvt3zWZYD6z5vYTcrtij2VZ9Zmni/
6 | UAaHqn9JdsBWLUEpVviYnhimNVvYFZeCXg/IdTQ+x4IRdiXNv5hEewIDAQABAoIBAQDl8Axy9XfW
7 | BLmkzkEiqoSwF0PsmVrPzH9KsnwLGH+QZlvjWd8SWYGN7u1507HvhF5N3drJoVU3O14nDY4TFQAa
8 | LlJ9VM35AApXaLyY1ERrN7u9ALKd2LUwYhM7Km539O4yUFYikE2nIPscEsA5ltpxOgUGCY7b7ez5
9 | NtD6nL1ZKauw7aNXmVAvmJTcuPxWmoktF3gDJKK2wxZuNGcJE0uFQEG4Z3BrWP7yoNuSK3dii2jm
10 | lpPHr0O/KnPQtzI3eguhe0TwUem/eYSdyzMyVx/YpwkzwtYL3sR5k0o9rKQLtvLzfAqdBxBurciz
11 | aaA/L0HIgAmOit1GJA2saMxTVPNhAoGBAPfgv1oeZxgxmotiCcMXFEQEWflzhWYTsXrhUIuz5jFu
12 | a39GLS99ZEErhLdrwj8rDDViRVJ5skOp9zFvlYAHs0xh92ji1E7V/ysnKBfsMrPkk5KSKPrnjndM
13 | oPdevWnVkgJ5jxFuNgxkOLMuG9i53B4yMvDTCRiIPMQ++N2iLDaRAoGBAO9v//mU8eVkQaoANf0Z
14 | oMjW8CN4xwWA2cSEIHkd9AfFkftuv8oyLDCG3ZAf0vrhrrtkrfa7ef+AUb69DNggq4mHQAYBp7L+
15 | k5DKzJrKuO0r+R0YbY9pZD1+/g9dVt91d6LQNepUE/yY2PP5CNoFmjedpLHMOPFdVgqDzDFxU8hL
16 | AoGBANDrr7xAJbqBjHVwIzQ4To9pb4BNeqDndk5Qe7fT3+/H1njGaC0/rXE0Qb7q5ySgnsCb3DvA
17 | cJyRM9SJ7OKlGt0FMSdJD5KG0XPIpAVNwgpXXH5MDJg09KHeh0kXo+QA6viFBi21y340NonnEfdf
18 | 54PX4ZGS/Xac1UK+pLkBB+zRAoGAf0AY3H3qKS2lMEI4bzEFoHeK3G895pDaK3TFBVmD7fV0Zhov
19 | 17fegFPMwOII8MisYm9ZfT2Z0s5Ro3s5rkt+nvLAdfC/PYPKzTLalpGSwomSNYJcB9HNMlmhkGzc
20 | 1JnLYT4iyUyx6pcZBmCd8bD0iwY/FzcgNDaUmbX9+XDvRA0CgYEAkE7pIPlE71qvfJQgoA9em0gI
21 | LAuE4Pu13aKiJnfft7hIjbK+5kyb3TysZvoyDnb3HOKvInK7vXbKuU4ISgxB2bB3HcYzQMGsz1qJ
22 | 2gG0N5hvJpzwwhbhXqFKA4zaaSrw622wDniAK5MlIE0tIAKKP4yxNGjoD2QYjhBGuhvkWKY=
23 | -----END RSA PRIVATE KEY-----
24 |
--------------------------------------------------------------------------------
/autogen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | autoreconf -vif
4 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | # -*- Autoconf -*-
2 | # Process this file with autoconf to produce a configure script.
3 |
4 | AC_PREREQ(2.61)
5 | AC_INIT([shairplay], [0.9.0], [juhovh@iki.fi])
6 | AC_CONFIG_MACRO_DIR([m4])
7 | AC_CONFIG_SRCDIR([src/shairplay.c])
8 | AC_CONFIG_HEADER([config.h])
9 | AM_INIT_AUTOMAKE([foreign])
10 |
11 | # Checks for programs.
12 | AC_PROG_CC
13 | AC_LIBTOOL_WIN32_DLL
14 | AC_PROG_LIBTOOL
15 |
16 | # Checks for libraries.
17 | LT_LIB_M
18 | LT_LIB_DLLOAD
19 |
20 | # Checks for header files.
21 | AC_HEADER_STDC
22 | if test yes = "$libltdl_cv_func_dlopen" || test yes = "$libltdl_cv_lib_dl_dlopen"
23 | then
24 | AC_CHECK_HEADERS([dns_sd.h], [],
25 | [AC_MSG_ERROR([Could not find dns_sd.h header, please install libavahi-compat-libdnssd-dev or equivalent.])])
26 | fi
27 |
28 | # Checks for typedefs, structures, and compiler characteristics.
29 |
30 | # Checks for library functions.
31 | AC_CHECK_LIB([socket],[connect])
32 | AC_CHECK_LIB([pthread],[pthread_create])
33 |
34 | # Custom check for os, similar to webkit
35 | AC_MSG_CHECKING([for native Win32])
36 | case "$host" in
37 | *-*-mingw*)
38 | os_win32=yes
39 | ;;
40 | *)
41 | os_win32=no
42 | ;;
43 | esac
44 | AC_MSG_RESULT([$os_win32])
45 |
46 | case "$host" in
47 | *-*-linux*)
48 | os_linux=yes
49 | ;;
50 | *-*-freebsd*)
51 | os_freebsd=yes
52 | ;;
53 | *-*-darwin*)
54 | os_darwin=yes
55 | ;;
56 | esac
57 |
58 | # OS conditionals
59 | AM_CONDITIONAL([OS_WIN32], [test x"$os_win32" = x"yes"])
60 | AM_CONDITIONAL([OS_UNIX], [test x"$os_win32" = x"no"])
61 | AM_CONDITIONAL([OS_LINUX], [test x"$os_linux" = x"yes"])
62 | AM_CONDITIONAL([OS_DARWIN], [test x"$os_darwin" = x"yes"])
63 | AM_CONDITIONAL([OS_FREEBSD], [test x"$os_freebsd" = x"yes"])
64 |
65 | # Custom check for libao
66 | PKG_CHECK_MODULES([libao], [ao >= 1.1.0], [have_libao=1], [have_libao=0])
67 | AM_CONDITIONAL([HAVE_LIBAO], [test "$have_libao" -eq 1])
68 | AM_COND_IF(HAVE_LIBAO,
69 | [AC_MSG_NOTICE([libao audio library found: Building both shairplay binary and libshairplay library.])],
70 | [AC_MSG_WARN([libao audio library not found: Building shairplay library only.])])
71 |
72 | # Optional playfair support
73 | AC_ARG_WITH([playfair],
74 | AS_HELP_STRING([--with-playfair], [Build with playfair support]))
75 | AM_CONDITIONAL([WITH_PLAYFAIR], [test x"$with_playfair" = x"yes"])
76 | AM_COND_IF([WITH_PLAYFAIR],
77 | [AC_DEFINE([HAVE_FAIRPLAY], [1],
78 | [Define if you have the libdl library or equivalent.])])
79 |
80 |
81 | AC_CONFIG_FILES(
82 | [Makefile]
83 | [include/Makefile]
84 | [src/Makefile]
85 | [src/lib/Makefile]
86 | [src/lib/alac/Makefile]
87 | [src/lib/crypto/Makefile]
88 | [src/lib/curve25519/Makefile]
89 | [src/lib/ed25519/Makefile]
90 | [src/lib/playfair/Makefile]
91 | )
92 | AC_OUTPUT
93 |
--------------------------------------------------------------------------------
/include/Makefile.am:
--------------------------------------------------------------------------------
1 | nobase_include_HEADERS = shairplay/dnssd.h shairplay/raop.h
2 |
--------------------------------------------------------------------------------
/include/shairplay/dnssd.h:
--------------------------------------------------------------------------------
1 | #ifndef DNSSD_H
2 | #define DNSSD_H
3 |
4 | #if defined(WIN32) && defined(DLL_EXPORT)
5 | # define DNSSD_API __declspec(dllexport)
6 | #else
7 | # define DNSSD_API
8 | #endif
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #define DNSSD_ERROR_NOERROR 0
15 | #define DNSSD_ERROR_HWADDRLEN 1
16 | #define DNSSD_ERROR_OUTOFMEM 2
17 | #define DNSSD_ERROR_LIBNOTFOUND 3
18 | #define DNSSD_ERROR_PROCNOTFOUND 4
19 |
20 | typedef struct dnssd_s dnssd_t;
21 |
22 | DNSSD_API dnssd_t *dnssd_init(int *error);
23 |
24 | DNSSD_API int dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port, const char *hwaddr, int hwaddrlen, int password);
25 | DNSSD_API int dnssd_register_airplay(dnssd_t *dnssd, const char *name, unsigned short port, const char *hwaddr, int hwaddrlen);
26 |
27 | DNSSD_API void dnssd_unregister_raop(dnssd_t *dnssd);
28 | DNSSD_API void dnssd_unregister_airplay(dnssd_t *dnssd);
29 |
30 | DNSSD_API void dnssd_destroy(dnssd_t *dnssd);
31 |
32 | #ifdef __cplusplus
33 | }
34 | #endif
35 | #endif
36 |
--------------------------------------------------------------------------------
/include/shairplay/raop.h:
--------------------------------------------------------------------------------
1 | #ifndef RAOP_H
2 | #define RAOP_H
3 |
4 | #if defined (WIN32) && defined(DLL_EXPORT)
5 | # define RAOP_API __declspec(dllexport)
6 | #else
7 | # define RAOP_API
8 | #endif
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 |
15 | /* Define syslog style log levels */
16 | #define RAOP_LOG_EMERG 0 /* system is unusable */
17 | #define RAOP_LOG_ALERT 1 /* action must be taken immediately */
18 | #define RAOP_LOG_CRIT 2 /* critical conditions */
19 | #define RAOP_LOG_ERR 3 /* error conditions */
20 | #define RAOP_LOG_WARNING 4 /* warning conditions */
21 | #define RAOP_LOG_NOTICE 5 /* normal but significant condition */
22 | #define RAOP_LOG_INFO 6 /* informational */
23 | #define RAOP_LOG_DEBUG 7 /* debug-level messages */
24 |
25 |
26 | typedef struct raop_s raop_t;
27 |
28 | typedef void (*raop_log_callback_t)(void *cls, int level, const char *msg);
29 |
30 | struct raop_callbacks_s {
31 | void* cls;
32 |
33 | /* Compulsory callback functions */
34 | void* (*audio_init)(void *cls, int bits, int channels, int samplerate);
35 | void (*audio_process)(void *cls, void *session, const void *buffer, int buflen);
36 | void (*audio_destroy)(void *cls, void *session);
37 |
38 | /* Optional but recommended callback functions */
39 | void (*audio_flush)(void *cls, void *session);
40 | void (*audio_set_volume)(void *cls, void *session, float volume);
41 | void (*audio_set_metadata)(void *cls, void *session, const void *buffer, int buflen);
42 | void (*audio_set_coverart)(void *cls, void *session, const void *buffer, int buflen);
43 | void (*audio_remote_control_id)(void *cls, const char *dacp_id, const char *active_remote_header);
44 | void (*audio_set_progress)(void *cls, void *session, unsigned int start, unsigned int curr, unsigned int end);
45 | };
46 | typedef struct raop_callbacks_s raop_callbacks_t;
47 |
48 | RAOP_API raop_t *raop_init(int max_clients, raop_callbacks_t *callbacks, const char *pemkey, int *error);
49 | RAOP_API raop_t *raop_init_from_keyfile(int max_clients, raop_callbacks_t *callbacks, const char *keyfile, int *error);
50 |
51 | RAOP_API void raop_set_log_level(raop_t *raop, int level);
52 | RAOP_API void raop_set_log_callback(raop_t *raop, raop_log_callback_t callback, void *cls);
53 |
54 | RAOP_API int raop_start(raop_t *raop, unsigned short *port, const char *hwaddr, int hwaddrlen, const char *password);
55 | RAOP_API int raop_is_running(raop_t *raop);
56 | RAOP_API void raop_stop(raop_t *raop);
57 |
58 | RAOP_API void raop_destroy(raop_t *raop);
59 |
60 | #ifdef __cplusplus
61 | }
62 | #endif
63 | #endif
64 |
--------------------------------------------------------------------------------
/src/Makefile.am:
--------------------------------------------------------------------------------
1 | SUBDIRS = lib
2 |
3 | AM_CPPFLAGS = -I$(top_srcdir)/include
4 |
5 | if HAVE_LIBAO
6 | bin_PROGRAMS = shairplay
7 | shairplay_SOURCES = shairplay.c
8 | shairplay_LDADD = lib/libshairplay.la
9 | shairplay_CFLAGS =
10 | shairplay_LDFLAGS = -static-libtool-libs
11 |
12 | shairplay_CFLAGS += $(libao_CFLAGS)
13 | shairplay_LDADD += $(libao_LIBS)
14 | endif
15 |
--------------------------------------------------------------------------------
/src/bindings/qt4/dnssdservice.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2012 Juho Vähä-Herttua
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #include "dnssdservice.h"
25 |
26 | DnssdService::DnssdService(QObject *parent) :
27 | QObject(parent)
28 | {
29 | }
30 |
31 | bool DnssdService::init()
32 | {
33 | int error;
34 | m_dnssd = dnssd_init(&error);
35 | if (!m_dnssd) {
36 | return false;
37 | }
38 | return true;
39 | }
40 |
41 | DnssdService::~DnssdService()
42 | {
43 | dnssd_destroy(m_dnssd);
44 | }
45 |
46 | void DnssdService::registerRaop(const QString & name, quint16 port, const QByteArray & hwaddr)
47 | {
48 | dnssd_register_raop(m_dnssd, name.toUtf8().data(), port, hwaddr.data(), hwaddr.size(), 0);
49 | }
50 |
51 | void DnssdService::unregisterRaop()
52 | {
53 | dnssd_unregister_raop(m_dnssd);
54 | }
55 |
56 | void DnssdService::registerAirplay(const QString &name, quint16 port, const QByteArray &hwaddr)
57 | {
58 | dnssd_register_airplay(m_dnssd, name.toUtf8().data(), port, hwaddr.data(), hwaddr.size());
59 | }
60 |
61 | void DnssdService::unregisterAirplay()
62 | {
63 | dnssd_unregister_airplay(m_dnssd);
64 | }
65 |
--------------------------------------------------------------------------------
/src/bindings/qt4/dnssdservice.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2012 Juho Vähä-Herttua
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef DNSSDSERVICE_H
25 | #define DNSSDSERVICE_H
26 |
27 | #include
28 |
29 | #include
30 |
31 | class DnssdService : public QObject
32 | {
33 | Q_OBJECT
34 | public:
35 | explicit DnssdService(QObject *parent = 0);
36 | ~DnssdService();
37 |
38 | bool init();
39 |
40 | void registerRaop(const QString & name, quint16 port, const QByteArray & hwaddr);
41 | void unregisterRaop();
42 |
43 | void registerAirplay(const QString & name, quint16 port, const QByteArray & hwaddr);
44 | void unregisterAirplay();
45 |
46 | private:
47 | dnssd_t * m_dnssd;
48 |
49 | signals:
50 |
51 | public slots:
52 |
53 | };
54 |
55 | #endif // DNSSDSERVICE_H
56 |
--------------------------------------------------------------------------------
/src/bindings/qt4/raopcallbackhandler.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2012 Juho Vähä-Herttua
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #include "raopcallbackhandler.h"
25 |
26 | RaopCallbackHandler::RaopCallbackHandler(QObject *parent) :
27 | QObject(parent)
28 | {
29 | }
30 |
31 | void RaopCallbackHandler::init(RaopAudioHandler *callbacks)
32 | {
33 | m_callbacks = callbacks;
34 | }
35 |
36 | void RaopCallbackHandler::audioInit(void *session, int bits, int channels, int samplerate)
37 | {
38 | void **retval = (void**)session;
39 | if (m_callbacks) {
40 | *retval = m_callbacks->audioInit(bits, channels, samplerate);
41 | }
42 | }
43 |
44 | void RaopCallbackHandler::audioProcess(void *session, void *buffer, int buflen)
45 | {
46 | if (m_callbacks) {
47 | m_callbacks->audioProcess(session, QByteArray((const char *)buffer, buflen));
48 | }
49 | }
50 |
51 | void RaopCallbackHandler::audioDestroy(void *session)
52 | {
53 | if (m_callbacks) {
54 | m_callbacks->audioDestroy(session);
55 | }
56 | }
57 |
58 | void RaopCallbackHandler::audioFlush(void *session)
59 | {
60 | if (m_callbacks) {
61 | m_callbacks->audioFlush(session);
62 | }
63 | }
64 |
65 | void RaopCallbackHandler::audioSetVolume(void *session, float volume)
66 | {
67 | if (m_callbacks) {
68 | m_callbacks->audioSetVolume(session, volume);
69 | }
70 | }
71 |
72 | void RaopCallbackHandler::audioSetMetadata(void *session, void *buffer, int buflen)
73 | {
74 | if (m_callbacks) {
75 | m_callbacks->audioSetMetadata(session, QByteArray((const char *)buffer, buflen));
76 | }
77 | }
78 |
79 | void RaopCallbackHandler::audioSetCoverart(void *session, void *buffer, int buflen)
80 | {
81 | if (m_callbacks) {
82 | m_callbacks->audioSetCoverart(session, QByteArray((const char *)buffer, buflen));
83 | }
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/src/bindings/qt4/raopcallbackhandler.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2012 Juho Vähä-Herttua
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef RAOPCALLBACKHANDLER_H
25 | #define RAOPCALLBACKHANDLER_H
26 |
27 | #include
28 |
29 | #include "raopcallbacks.h"
30 |
31 | class RaopCallbackHandler : public QObject
32 | {
33 | Q_OBJECT
34 | public:
35 | explicit RaopCallbackHandler(QObject *parent = 0);
36 | void init(RaopAudioHandler *callbacks);
37 |
38 | private:
39 | RaopAudioHandler * m_callbacks;
40 |
41 | signals:
42 |
43 | public slots:
44 | void audioInit(void *session, int bits, int channels, int samplerate);
45 | void audioProcess(void *session, void *buffer, int buflen);
46 | void audioDestroy(void *session);
47 | void audioFlush(void *session);
48 | void audioSetVolume(void *session, float volume);
49 | void audioSetMetadata(void *session, void *buffer, int buflen);
50 | void audioSetCoverart(void *session, void *buffer, int buflen);
51 | };
52 |
53 | #endif // RAOPCALLBACKHANDLER_H
54 |
--------------------------------------------------------------------------------
/src/bindings/qt4/raopcallbacks.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2012 Juho Vähä-Herttua
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef RAOPCALLBACKS_H
25 | #define RAOPCALLBACKS_H
26 |
27 | #include
28 |
29 | class RaopLogHandler : public QObject
30 | {
31 | Q_OBJECT
32 | public:
33 | explicit RaopLogHandler(QObject *parent = 0) : QObject(parent) {}
34 |
35 | virtual void logCallback(int level, const char *msg) = 0;
36 | };
37 |
38 | class RaopAudioHandler : public QObject
39 | {
40 | Q_OBJECT
41 | public:
42 | explicit RaopAudioHandler(QObject *parent = 0) : QObject(parent) {}
43 |
44 | virtual void *audioInit(int bits, int channels, int samplerate) = 0;
45 | virtual void audioProcess(void *session, const QByteArray & buffer) = 0;
46 | virtual void audioDestroy(void *session) = 0;
47 |
48 | virtual void audioFlush(void *session) { Q_UNUSED(session) }
49 | virtual void audioSetVolume(void *session, float volume) { Q_UNUSED(session) Q_UNUSED(volume) }
50 | virtual void audioSetMetadata(void *session, const QByteArray & buffer) { Q_UNUSED(session) Q_UNUSED(buffer) }
51 | virtual void audioSetCoverart(void *session, const QByteArray & buffer) { Q_UNUSED(session) Q_UNUSED(buffer) }
52 | };
53 |
54 | #endif // RAOPCALLBACKS_H
55 |
--------------------------------------------------------------------------------
/src/bindings/qt4/raopservice.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2012 Juho Vähä-Herttua
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef RAOPSERVICE_H
25 | #define RAOPSERVICE_H
26 |
27 | #include
28 |
29 | #include
30 |
31 | #include "raopcallbacks.h"
32 |
33 | class RaopService : public QObject
34 | {
35 | Q_OBJECT
36 | public:
37 | explicit RaopService(QObject *parent = 0);
38 | ~RaopService();
39 |
40 | bool init(int max_clients, RaopAudioHandler *callbacks);
41 | void setLogLevel(int level);
42 | void setLogHandler(RaopLogHandler *logger);
43 | bool start(quint16 port, const QByteArray & hwaddr);
44 | bool isRunning();
45 | void stop();
46 |
47 | private:
48 | raop_t * m_raop;
49 |
50 | signals:
51 |
52 | public slots:
53 |
54 | };
55 |
56 | #endif // RAOPSERVICE_H
57 |
--------------------------------------------------------------------------------
/src/lib/Makefile.am:
--------------------------------------------------------------------------------
1 | if WITH_PLAYFAIR
2 | PLAYFAIR_SUBDIR = playfair
3 | PLAYFAIR_LIBADD = playfair/libplayfair.la
4 | FAIRPLAY_SOURCE = fairplay_playfair.c
5 | else
6 | FAIRPLAY_SOURCE = fairplay_dummy.c
7 | endif
8 |
9 | SUBDIRS = crypto alac curve25519 ed25519 $(PLAYFAIR_SUBDIR)
10 |
11 | AM_CPPFLAGS = -I$(top_srcdir)/include/shairplay
12 |
13 | lib_LTLIBRARIES = libshairplay.la
14 | libshairplay_la_SOURCES = base64.c base64.h digest.c digest.h dnssd.c dnssdint.h http_parser.c http_parser.h http_request.c http_request.h http_response.c http_response.h httpd.c httpd.h logger.c logger.h netutils.c netutils.h raop.c raop_buffer.c raop_buffer.h raop_rtp.c raop_rtp.h rsakey.c rsakey.h rsapem.c rsapem.h sdp.c sdp.h aes_ctr.c aes_ctr.h pairing.c pairing.h utils.c utils.h $(FAIRPLAY_SOURCE) fairplay.h plist.c plist.h compat.h memalign.h sockets.h threads.h
15 | libshairplay_la_CPPFLAGS = $(AM_CPPFLAGS)
16 |
17 | # This library depends on 3rd party libraries
18 | libshairplay_la_LIBADD = crypto/libcrypto.la alac/libalac.la curve25519/libcurve25519.la ed25519/libed25519.la $(PLAYFAIR_LIBADD)
19 | libshairplay_la_LDFLAGS = -no-undefined -version-info 0:0:0
20 |
21 | ### Update -version-info above with the following rules
22 | # 1. Start with version information of ‘0:0:0’ for each libtool library.
23 | # 2. Update the version information only immediately before a public release of
24 | # your software. More frequent updates are unnecessary, and only guarantee
25 | # that the current interface number gets larger faster.
26 | # 3. If the library source code has changed at all since the last update, then
27 | # increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
28 | # 4. If any interfaces have been added, removed, or changed since the last
29 | # update, increment current, and set revision to 0.
30 | # 5. If any interfaces have been added since the last public release, then
31 | # increment age.
32 | # 6. If any interfaces have been removed or changed since the last public
33 | # release, then set age to 0.
34 | ###
35 |
36 | libshairplay_la_LIBADD += $(LIBADD_DLOPEN)
37 | libshairplay_la_LIBADD += $(LIBM)
38 |
39 | if OS_WIN32
40 | libshairplay_la_CPPFLAGS += -DDLL_EXPORT
41 | libshairplay_la_LDFLAGS += -lws2_32 -lwinmm
42 | else
43 | libshairplay_la_LDFLAGS += -export-symbols-regex '^(raop|dnssd)'
44 | endif
45 |
--------------------------------------------------------------------------------
/src/lib/aes_ctr.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2018 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include
16 | #include
17 |
18 | #include "aes_ctr.h"
19 |
20 | static void
21 | ctr128_inc(uint8_t *counter)
22 | {
23 | uint32_t n = 16, c = 1;
24 |
25 | do {
26 | --n;
27 | c += counter[n];
28 | counter[n] = (uint8_t) c;
29 | c >>= 8;
30 | } while (n);
31 | }
32 |
33 | void
34 | AES_ctr_set_key(AES_CTR_CTX *ctx, const uint8_t *key, const uint8_t *nonce, AES_MODE mode)
35 | {
36 | assert(ctx);
37 |
38 | /* Setting IV as nonce, but it will be overridden in encrypt */
39 | AES_set_key(&ctx->aes_ctx, key, nonce, mode);
40 | memcpy(ctx->counter, nonce, AES_BLOCKSIZE);
41 | memset(ctx->state, 0, AES_BLOCKSIZE);
42 | ctx->available = 0;
43 | }
44 |
45 | void
46 | AES_ctr_encrypt(AES_CTR_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
47 | {
48 | unsigned char block[16];
49 | int msgidx, i;
50 |
51 | assert(ctx);
52 | assert(msg);
53 | assert(out);
54 |
55 | msgidx = 0;
56 | while (msgidx < length) {
57 | if (ctx->available == 0) {
58 | /* Generate a new block into state if we have no bytes */
59 | memset(ctx->aes_ctx.iv, 0, AES_IV_SIZE);
60 | AES_cbc_encrypt(&ctx->aes_ctx, ctx->counter, ctx->state, AES_BLOCKSIZE);
61 | ctx->available = AES_BLOCKSIZE;
62 | ctr128_inc(ctx->counter);
63 | }
64 | for (i=0; iavailable && msgidxstate[AES_BLOCKSIZE-ctx->available+i];
66 | }
67 | ctx->available -= i;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/lib/aes_ctr.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2018 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef AES_CTR_H
16 | #define AES_CTR_H
17 |
18 | #include
19 | #include "crypto/crypto.h"
20 |
21 | typedef struct aes_ctr_key_st {
22 | AES_CTX aes_ctx;
23 | uint8_t counter[AES_BLOCKSIZE];
24 | uint8_t state[AES_BLOCKSIZE];
25 | uint8_t available;
26 | } AES_CTR_CTX;
27 |
28 | void AES_ctr_set_key(AES_CTR_CTX *ctx, const uint8_t *key, const uint8_t *nonce, AES_MODE mode);
29 | void AES_ctr_encrypt(AES_CTR_CTX *ctx, const uint8_t *msg, uint8_t *out, int length);
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/src/lib/alac/Makefile.am:
--------------------------------------------------------------------------------
1 | noinst_LTLIBRARIES = libalac.la
2 | libalac_la_SOURCES = alac.c alac.h stdint_win.h
3 |
--------------------------------------------------------------------------------
/src/lib/alac/alac.h:
--------------------------------------------------------------------------------
1 | #ifndef __ALAC__DECOMP_H
2 | #define __ALAC__DECOMP_H
3 |
4 | #include
5 |
6 | typedef struct alac_file alac_file;
7 |
8 | alac_file *alac_create(int samplesize, int numchannels);
9 | void alac_decode_frame(alac_file *alac,
10 | unsigned char *inbuffer,
11 | void *outbuffer, int *outputsize);
12 | void alac_set_info(alac_file *alac, char *inputbuffer);
13 | void alac_allocate_buffers(alac_file *alac);
14 | void alac_free(alac_file *alac);
15 |
16 | struct alac_file
17 | {
18 | unsigned char *input_buffer;
19 | int input_buffer_bitaccumulator; /* used so we can do arbitary
20 | bit reads */
21 |
22 | int samplesize;
23 | int numchannels;
24 | int bytespersample;
25 |
26 |
27 | /* buffers */
28 | int32_t *predicterror_buffer_a;
29 | int32_t *predicterror_buffer_b;
30 |
31 | int32_t *outputsamples_buffer_a;
32 | int32_t *outputsamples_buffer_b;
33 |
34 | int32_t *uncompressed_bytes_buffer_a;
35 | int32_t *uncompressed_bytes_buffer_b;
36 |
37 |
38 |
39 | /* stuff from setinfo */
40 | uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */
41 | uint8_t setinfo_7a; /* 0x00 */
42 | uint8_t setinfo_sample_size; /* 0x10 */
43 | uint8_t setinfo_rice_historymult; /* 0x28 */
44 | uint8_t setinfo_rice_initialhistory; /* 0x0a */
45 | uint8_t setinfo_rice_kmodifier; /* 0x0e */
46 | uint8_t setinfo_7f; /* 0x02 */
47 | uint16_t setinfo_80; /* 0x00ff */
48 | uint32_t setinfo_82; /* 0x000020e7 */ /* max sample size?? */
49 | uint32_t setinfo_86; /* 0x00069fe4 */ /* bit rate (avarge)?? */
50 | uint32_t setinfo_8a_rate; /* 0x0000ac44 */
51 | /* end setinfo stuff */
52 |
53 | };
54 |
55 |
56 | #endif /* __ALAC__DECOMP_H */
57 |
58 |
--------------------------------------------------------------------------------
/src/lib/alac/stdint_win.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef ALAC_STDINT_WIN_H__
3 | #define ALAC_STDINT_WIN_H__
4 |
5 | typedef signed char int8_t;
6 | typedef signed short int16_t;
7 | typedef signed int int32_t;
8 | typedef signed __int64 int64_t;
9 | typedef unsigned char uint8_t;
10 | typedef unsigned short uint16_t;
11 | typedef unsigned int uint32_t;
12 | typedef unsigned __int64 uint64_t;
13 |
14 | #endif // ALAC_STDINT_WIN_H__
--------------------------------------------------------------------------------
/src/lib/base64.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef BASE64_H
16 | #define BASE64_H
17 |
18 | typedef struct base64_s base64_t;
19 |
20 | base64_t *base64_init(const char *charlist, int use_padding, int skip_spaces);
21 |
22 | int base64_encoded_length(base64_t *base64, int srclen);
23 |
24 | int base64_encode(base64_t *base64, char *dst, const unsigned char *src, int srclen);
25 | int base64_decode(base64_t *base64, unsigned char **dst, const char *src, int srclen);
26 |
27 | void base64_destroy(base64_t *base64);
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/src/lib/compat.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef COMPAT_H
16 | #define COMPAT_H
17 |
18 | #if defined(WIN32)
19 | #include
20 | #include
21 | #ifndef snprintf
22 | #define snprintf _snprintf
23 | #endif
24 | #else
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #endif
36 |
37 | #include "memalign.h"
38 | #include "sockets.h"
39 | #include "threads.h"
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/src/lib/crypto/Makefile.am:
--------------------------------------------------------------------------------
1 | noinst_LTLIBRARIES = libcrypto.la
2 | libcrypto_la_SOURCES = bigint.c bigint.h bigint_impl.h aes.c hmac.c md5.c rc4.c sha1.c crypto.h os_port.h config.h
3 |
4 |
--------------------------------------------------------------------------------
/src/lib/crypto/bigint.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2007, Cameron Rich
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright notice,
10 | * this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | * * Neither the name of the axTLS project nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #ifndef BIGINT_HEADER
32 | #define BIGINT_HEADER
33 |
34 | #include "crypto.h"
35 |
36 | BI_CTX *bi_initialize(void);
37 | void bi_terminate(BI_CTX *ctx);
38 | void bi_permanent(bigint *bi);
39 | void bi_depermanent(bigint *bi);
40 | void bi_clear_cache(BI_CTX *ctx);
41 | void bi_free(BI_CTX *ctx, bigint *bi);
42 | bigint *bi_copy(bigint *bi);
43 | bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
44 | void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
45 | bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
46 | bigint *int_to_bi(BI_CTX *ctx, comp i);
47 |
48 | /* the functions that actually do something interesting */
49 | bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
50 | bigint *bi_subtract(BI_CTX *ctx, bigint *bia,
51 | bigint *bib, int *is_negative);
52 | bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
53 | bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
54 | bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
55 | bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
56 | int bi_compare(bigint *bia, bigint *bib);
57 | void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
58 | void bi_free_mod(BI_CTX *ctx, int mod_offset);
59 |
60 | #ifdef CONFIG_SSL_FULL_MODE
61 | void bi_print(const char *label, bigint *bi);
62 | bigint *bi_str_import(BI_CTX *ctx, const char *data);
63 | #endif
64 |
65 | /**
66 | * @def bi_mod
67 | * Find the residue of B. bi_set_mod() must be called before hand.
68 | */
69 | #define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
70 |
71 | /**
72 | * bi_residue() is technically the same as bi_mod(), but it uses the
73 | * appropriate reduction technique (which is bi_mod() when doing classical
74 | * reduction).
75 | */
76 | #if defined(CONFIG_BIGINT_MONTGOMERY)
77 | #define bi_residue(A, B) bi_mont(A, B)
78 | bigint *bi_mont(BI_CTX *ctx, bigint *bixy);
79 | #elif defined(CONFIG_BIGINT_BARRETT)
80 | #define bi_residue(A, B) bi_barrett(A, B)
81 | bigint *bi_barrett(BI_CTX *ctx, bigint *bi);
82 | #else /* if defined(CONFIG_BIGINT_CLASSICAL) */
83 | #define bi_residue(A, B) bi_mod(A, B)
84 | #endif
85 |
86 | #ifdef CONFIG_BIGINT_SQUARE
87 | bigint *bi_square(BI_CTX *ctx, bigint *bi);
88 | #else
89 | #define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
90 | #endif
91 |
92 | #ifdef CONFIG_BIGINT_CRT
93 | bigint *bi_crt(BI_CTX *ctx, bigint *bi,
94 | bigint *dP, bigint *dQ,
95 | bigint *p, bigint *q,
96 | bigint *qInv);
97 | #endif
98 |
99 | #endif
100 |
--------------------------------------------------------------------------------
/src/lib/crypto/config.h:
--------------------------------------------------------------------------------
1 |
2 | #define CONFIG_BIGINT_BARRETT 1
3 | #define CONFIG_BIGINT_CRT 1
4 | #define CONFIG_BIGINT_SQUARE 1
5 | #define CONFIG_BIGINT_32BIT 1
6 |
7 |
--------------------------------------------------------------------------------
/src/lib/crypto/hmac.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2007, Cameron Rich
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright notice,
10 | * this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | * * Neither the name of the axTLS project nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | /**
32 | * HMAC implementation - This code was originally taken from RFC2104
33 | * See http://www.ietf.org/rfc/rfc2104.txt and
34 | * http://www.faqs.org/rfcs/rfc2202.html
35 | */
36 |
37 | #include
38 | #include "os_port.h"
39 | #include "crypto.h"
40 |
41 | /**
42 | * Perform HMAC-MD5
43 | * NOTE: does not handle keys larger than the block size.
44 | */
45 | void hmac_md5(const uint8_t *msg, int length, const uint8_t *key,
46 | int key_len, uint8_t *digest)
47 | {
48 | MD5_CTX context;
49 | uint8_t k_ipad[64];
50 | uint8_t k_opad[64];
51 | int i;
52 |
53 | memset(k_ipad, 0, sizeof k_ipad);
54 | memset(k_opad, 0, sizeof k_opad);
55 | memcpy(k_ipad, key, key_len);
56 | memcpy(k_opad, key, key_len);
57 |
58 | for (i = 0; i < 64; i++)
59 | {
60 | k_ipad[i] ^= 0x36;
61 | k_opad[i] ^= 0x5c;
62 | }
63 |
64 | MD5_Init(&context);
65 | MD5_Update(&context, k_ipad, 64);
66 | MD5_Update(&context, msg, length);
67 | MD5_Final(digest, &context);
68 | MD5_Init(&context);
69 | MD5_Update(&context, k_opad, 64);
70 | MD5_Update(&context, digest, MD5_SIZE);
71 | MD5_Final(digest, &context);
72 | }
73 |
74 | /**
75 | * Perform HMAC-SHA1
76 | * NOTE: does not handle keys larger than the block size.
77 | */
78 | void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
79 | int key_len, uint8_t *digest)
80 | {
81 | SHA1_CTX context;
82 | uint8_t k_ipad[64];
83 | uint8_t k_opad[64];
84 | int i;
85 |
86 | memset(k_ipad, 0, sizeof k_ipad);
87 | memset(k_opad, 0, sizeof k_opad);
88 | memcpy(k_ipad, key, key_len);
89 | memcpy(k_opad, key, key_len);
90 |
91 | for (i = 0; i < 64; i++)
92 | {
93 | k_ipad[i] ^= 0x36;
94 | k_opad[i] ^= 0x5c;
95 | }
96 |
97 | SHA1_Init(&context);
98 | SHA1_Update(&context, k_ipad, 64);
99 | SHA1_Update(&context, msg, length);
100 | SHA1_Final(digest, &context);
101 | SHA1_Init(&context);
102 | SHA1_Update(&context, k_opad, 64);
103 | SHA1_Update(&context, digest, SHA1_SIZE);
104 | SHA1_Final(digest, &context);
105 | }
106 |
--------------------------------------------------------------------------------
/src/lib/crypto/rc4.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2007, Cameron Rich
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright notice,
10 | * this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | * * Neither the name of the axTLS project nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | /**
32 | * An implementation of the RC4/ARC4 algorithm.
33 | * Originally written by Christophe Devine.
34 | */
35 |
36 | #include
37 | #include "os_port.h"
38 | #include "crypto.h"
39 |
40 | /**
41 | * Get ready for an encrypt/decrypt operation
42 | */
43 | void RC4_setup(RC4_CTX *ctx, const uint8_t *key, int length)
44 | {
45 | int i, j = 0, k = 0, a;
46 | uint8_t *m;
47 |
48 | ctx->x = 0;
49 | ctx->y = 0;
50 | m = ctx->m;
51 |
52 | for (i = 0; i < 256; i++)
53 | m[i] = i;
54 |
55 | for (i = 0; i < 256; i++)
56 | {
57 | a = m[i];
58 | j = (uint8_t)(j + a + key[k]);
59 | m[i] = m[j];
60 | m[j] = a;
61 |
62 | if (++k >= length)
63 | k = 0;
64 | }
65 | }
66 |
67 | /**
68 | * Perform the encrypt/decrypt operation (can use it for either since
69 | * this is a stream cipher).
70 | * NOTE: *msg and *out must be the same pointer (performance tweak)
71 | */
72 | void RC4_crypt(RC4_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
73 | {
74 | int i;
75 | uint8_t *m, x, y, a, b;
76 |
77 | x = ctx->x;
78 | y = ctx->y;
79 | m = ctx->m;
80 |
81 | for (i = 0; i < length; i++)
82 | {
83 | a = m[++x];
84 | y += a;
85 | m[x] = b = m[y];
86 | m[y] = a;
87 | out[i] ^= m[(uint8_t)(a + b)];
88 | }
89 |
90 | ctx->x = x;
91 | ctx->y = y;
92 | }
93 |
--------------------------------------------------------------------------------
/src/lib/curve25519/Makefile.am:
--------------------------------------------------------------------------------
1 | noinst_LTLIBRARIES = libcurve25519.la
2 | libcurve25519_la_SOURCES = curve25519-donna.c
3 |
--------------------------------------------------------------------------------
/src/lib/curve25519/curve25519.h:
--------------------------------------------------------------------------------
1 | #ifndef CURVE25519_DONNA_H
2 | #define CURVE25519_DONNA_H
3 |
4 | static const unsigned char kCurve25519BasePoint[32] = { 9 };
5 |
6 | int curve25519_donna(unsigned char *mypublic, const unsigned char *secret, const unsigned char *basepoint);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/src/lib/digest.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "compat.h"
7 | #include "utils.h"
8 | #include "crypto/crypto.h"
9 |
10 | void
11 | digest_md5_to_hex(const unsigned char *md5buf, char *md5hex)
12 | {
13 | int i;
14 | for (i=0; i>4;
16 | md5hex[i] = (val<10) ? '0'+val : 'a'+(val-10);
17 | }
18 | }
19 |
20 | void
21 | digest_get_response(const char *username, const char *realm,
22 | const char *password, const char *nonce,
23 | const char *method, const char *uri,
24 | char *response)
25 | {
26 | MD5_CTX md5ctx;
27 | unsigned char md5buf[MD5_SIZE];
28 | char md5hex[MD5_SIZE*2];
29 |
30 | /* Calculate first inner MD5 hash */
31 | MD5_Init(&md5ctx);
32 | MD5_Update(&md5ctx, (const unsigned char *)username, strlen(username));
33 | MD5_Update(&md5ctx, (const unsigned char *)":", 1);
34 | MD5_Update(&md5ctx, (const unsigned char *)realm, strlen(realm));
35 | MD5_Update(&md5ctx, (const unsigned char *)":", 1);
36 | MD5_Update(&md5ctx, (const unsigned char *)password, strlen(password));
37 | MD5_Final(md5buf, &md5ctx);
38 | digest_md5_to_hex(md5buf, md5hex);
39 |
40 | /* Calculate second inner MD5 hash */
41 | MD5_Init(&md5ctx);
42 | MD5_Update(&md5ctx, (const unsigned char *)method, strlen(method));
43 | MD5_Update(&md5ctx, (const unsigned char *)":", 1);
44 | MD5_Update(&md5ctx, (const unsigned char *)uri, strlen(uri));
45 | MD5_Final(md5buf, &md5ctx);
46 |
47 | /* Calculate outer MD5 hash */
48 | MD5_Init(&md5ctx);
49 | MD5_Update(&md5ctx, (const unsigned char *)md5hex, sizeof(md5hex));
50 | MD5_Update(&md5ctx, (const unsigned char *)":", 1);
51 | MD5_Update(&md5ctx, (const unsigned char *)nonce, strlen(nonce));
52 | MD5_Update(&md5ctx, (const unsigned char *)":", 1);
53 | digest_md5_to_hex(md5buf, md5hex);
54 | MD5_Update(&md5ctx, (const unsigned char *)md5hex, sizeof(md5hex));
55 | MD5_Final(md5buf, &md5ctx);
56 |
57 | /* Store the final result to response */
58 | digest_md5_to_hex(md5buf, response);
59 | }
60 |
61 | void
62 | digest_generate_nonce(char *result, int resultlen)
63 | {
64 | MD5_CTX md5ctx;
65 | unsigned char md5buf[MD5_SIZE];
66 | char md5hex[MD5_SIZE*2];
67 | unsigned int time;
68 |
69 | SYSTEM_GET_TIME(time);
70 |
71 | MD5_Init(&md5ctx);
72 | MD5_Update(&md5ctx, (unsigned char *)&time, sizeof(time));
73 | MD5_Final(md5buf, &md5ctx);
74 | digest_md5_to_hex(md5buf, md5hex);
75 |
76 | memset(result, 0, resultlen);
77 | strncpy(result, md5hex, resultlen-1);
78 | }
79 |
80 | int
81 | digest_is_valid(const char *our_realm, const char *password,
82 | const char *our_nonce, const char *method,
83 | const char *our_uri, const char *authorization)
84 | {
85 | char *auth;
86 | char *current;
87 | char *value;
88 | int success;
89 |
90 | /* Get values from authorization */
91 | char *username = NULL;
92 | char *realm = NULL;
93 | char *nonce = NULL;
94 | char *uri = NULL;
95 | char *response = NULL;
96 |
97 | /* Buffer for our response */
98 | char our_response[MD5_SIZE*2+1];
99 |
100 | if (!authorization) {
101 | return 0;
102 | }
103 | current = auth = strdup(authorization);
104 | if (!auth) {
105 | return 0;
106 | }
107 |
108 | /* Check that the type is digest */
109 | if (strncmp("Digest", current, 6)) {
110 | free(auth);
111 | return 0;
112 | }
113 | current += 6;
114 |
115 | while ((value = utils_strsep(¤t, ",")) != NULL) {
116 | char *first, *last;
117 |
118 | /* Find first and last characters */
119 | first = value;
120 | last = value+strlen(value)-1;
121 |
122 | /* Trim spaces from the value */
123 | while (*first == ' ' && first < last) first++;
124 | while (*last == ' ' && last > first) last--;
125 |
126 | /* Validate the last character */
127 | if (*last != '"') continue;
128 | else *last = '\0';
129 |
130 | /* Store value if it is relevant */
131 | if (!strncmp("username=\"", first, 10)) {
132 | username = first+10;
133 | } else if (!strncmp("realm=\"", first, 7)) {
134 | realm = first+7;
135 | } else if (!strncmp("nonce=\"", first, 7)) {
136 | nonce = first+7;
137 | } else if (!strncmp("uri=\"", first, 5)) {
138 | uri = first+5;
139 | } else if (!strncmp("response=\"", first, 10)) {
140 | response = first+10;
141 | }
142 | }
143 |
144 | if (!username || !realm || !nonce || !uri || !response) {
145 | free(auth);
146 | return 0;
147 | }
148 | if (strcmp(realm, our_realm) || strcmp(nonce, our_nonce) || strcmp(uri, our_uri)) {
149 | free(auth);
150 | return 0;
151 | }
152 |
153 | /* Calculate our response */
154 | memset(our_response, 0, sizeof(our_response));
155 | digest_get_response(username, realm, password, nonce,
156 | method, uri, our_response);
157 | success = !strcmp(response, our_response);
158 | free(auth);
159 |
160 | return success;
161 | }
162 |
163 |
164 |
--------------------------------------------------------------------------------
/src/lib/digest.h:
--------------------------------------------------------------------------------
1 | #ifndef DIGEST_H
2 | #define DIGEST_H
3 |
4 | void digest_generate_nonce(char *result, int resultlen);
5 | int digest_is_valid(const char *our_realm, const char *password,
6 | const char *our_nonce, const char *method,
7 | const char *our_uri, const char *authorization);
8 |
9 | #endif
10 |
--------------------------------------------------------------------------------
/src/lib/dnssdint.h:
--------------------------------------------------------------------------------
1 | #ifndef DNSSDINT_H
2 | #define DNSSDINT_H
3 |
4 | #define RAOP_TXTVERS "1"
5 | #define RAOP_CH "2" /* Audio channels: 2 */
6 | #define RAOP_CN "0,1" /* Audio codec: PCM, ALAC */
7 | #define RAOP_ET "0,1" /* Encryption type: none, RSA */
8 | #define RAOP_SV "false"
9 | #define RAOP_DA "true"
10 | #define RAOP_SR "44100"
11 | #define RAOP_SS "16" /* Sample size: 16 */
12 | #define RAOP_VN "3"
13 | #define RAOP_TP "TCP,UDP"
14 | #define RAOP_MD "0,1,2" /* Metadata: text, artwork, progress */
15 | #define RAOP_SM "false"
16 | #define RAOP_EK "1"
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/src/lib/ed25519/Makefile.am:
--------------------------------------------------------------------------------
1 | noinst_LTLIBRARIES = libed25519.la
2 | libed25519_la_SOURCES = add_scalar.c fe.c ge.c keypair.c sc.c seed.c sha512.c sign.c verify.c
3 |
4 |
--------------------------------------------------------------------------------
/src/lib/ed25519/add_scalar.c:
--------------------------------------------------------------------------------
1 | #include "ed25519.h"
2 | #include "ge.h"
3 | #include "sc.h"
4 | #include "sha512.h"
5 |
6 |
7 | /* see http://crypto.stackexchange.com/a/6215/4697 */
8 | void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) {
9 | const unsigned char SC_1[32] = {1}; /* scalar with value 1 */
10 |
11 | unsigned char n[32];
12 | ge_p3 nB;
13 | ge_p1p1 A_p1p1;
14 | ge_p3 A;
15 | ge_p3 public_key_unpacked;
16 | ge_cached T;
17 |
18 | sha512_context hash;
19 | unsigned char hashbuf[64];
20 |
21 | int i;
22 |
23 | /* copy the scalar and clear highest bit */
24 | for (i = 0; i < 31; ++i) {
25 | n[i] = scalar[i];
26 | }
27 | n[31] = scalar[31] & 127;
28 |
29 | /* private key: a = n + t */
30 | if (private_key) {
31 | sc_muladd(private_key, SC_1, n, private_key);
32 |
33 | // https://github.com/orlp/ed25519/issues/3
34 | sha512_init(&hash);
35 | sha512_update(&hash, private_key + 32, 32);
36 | sha512_update(&hash, scalar, 32);
37 | sha512_final(&hash, hashbuf);
38 | for (i = 0; i < 32; ++i) {
39 | private_key[32 + i] = hashbuf[i];
40 | }
41 | }
42 |
43 | /* public key: A = nB + T */
44 | if (public_key) {
45 | /* if we know the private key we don't need a point addition, which is faster */
46 | /* using a "timing attack" you could find out wether or not we know the private
47 | key, but this information seems rather useless - if this is important pass
48 | public_key and private_key seperately in 2 function calls */
49 | if (private_key) {
50 | ge_scalarmult_base(&A, private_key);
51 | } else {
52 | /* unpack public key into T */
53 | ge_frombytes_negate_vartime(&public_key_unpacked, public_key);
54 | fe_neg(public_key_unpacked.X, public_key_unpacked.X); /* undo negate */
55 | fe_neg(public_key_unpacked.T, public_key_unpacked.T); /* undo negate */
56 | ge_p3_to_cached(&T, &public_key_unpacked);
57 |
58 | /* calculate n*B */
59 | ge_scalarmult_base(&nB, n);
60 |
61 | /* A = n*B + T */
62 | ge_add(&A_p1p1, &nB, &T);
63 | ge_p1p1_to_p3(&A, &A_p1p1);
64 | }
65 |
66 | /* pack public key */
67 | ge_p3_tobytes(public_key, &A);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/lib/ed25519/ed25519.h:
--------------------------------------------------------------------------------
1 | #ifndef ED25519_H
2 | #define ED25519_H
3 |
4 | #include
5 |
6 | #if defined(_WIN32)
7 | #if defined(ED25519_BUILD_DLL)
8 | #define ED25519_DECLSPEC __declspec(dllexport)
9 | #elif defined(ED25519_DLL)
10 | #define ED25519_DECLSPEC __declspec(dllimport)
11 | #else
12 | #define ED25519_DECLSPEC
13 | #endif
14 | #else
15 | #define ED25519_DECLSPEC
16 | #endif
17 |
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #ifndef ED25519_NO_SEED
24 | int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed);
25 | #endif
26 |
27 | void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed);
28 | void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key);
29 | int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key);
30 | void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar);
31 | void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key);
32 |
33 |
34 | #ifdef __cplusplus
35 | }
36 | #endif
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/src/lib/ed25519/fe.h:
--------------------------------------------------------------------------------
1 | #ifndef FE_H
2 | #define FE_H
3 |
4 | #include "fixedint.h"
5 |
6 |
7 | /*
8 | fe means field element.
9 | Here the field is \Z/(2^255-19).
10 | An element t, entries t[0]...t[9], represents the integer
11 | t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
12 | Bounds on each t[i] vary depending on context.
13 | */
14 |
15 |
16 | typedef int32_t fe[10];
17 |
18 |
19 | void fe_0(fe h);
20 | void fe_1(fe h);
21 |
22 | void fe_frombytes(fe h, const unsigned char *s);
23 | void fe_tobytes(unsigned char *s, const fe h);
24 |
25 | void fe_copy(fe h, const fe f);
26 | int fe_isnegative(const fe f);
27 | int fe_isnonzero(const fe f);
28 | void fe_cmov(fe f, const fe g, unsigned int b);
29 | void fe_cswap(fe f, fe g, unsigned int b);
30 |
31 | void fe_neg(fe h, const fe f);
32 | void fe_add(fe h, const fe f, const fe g);
33 | void fe_invert(fe out, const fe z);
34 | void fe_sq(fe h, const fe f);
35 | void fe_sq2(fe h, const fe f);
36 | void fe_mul(fe h, const fe f, const fe g);
37 | void fe_mul121666(fe h, fe f);
38 | void fe_pow22523(fe out, const fe z);
39 | void fe_sub(fe h, const fe f, const fe g);
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/src/lib/ed25519/fixedint.h:
--------------------------------------------------------------------------------
1 | /*
2 | Portable header to provide the 32 and 64 bits type.
3 |
4 | Not a compatible replacement for , do not blindly use it as such.
5 | */
6 |
7 | #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED)
8 | #include
9 | #define FIXEDINT_H_INCLUDED
10 |
11 | #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
12 | #include
13 | #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
14 | #endif
15 | #endif
16 |
17 |
18 | #ifndef FIXEDINT_H_INCLUDED
19 | #define FIXEDINT_H_INCLUDED
20 |
21 | #include
22 |
23 | /* (u)int32_t */
24 | #ifndef uint32_t
25 | #if (ULONG_MAX == 0xffffffffUL)
26 | typedef unsigned long uint32_t;
27 | #elif (UINT_MAX == 0xffffffffUL)
28 | typedef unsigned int uint32_t;
29 | #elif (USHRT_MAX == 0xffffffffUL)
30 | typedef unsigned short uint32_t;
31 | #endif
32 | #endif
33 |
34 |
35 | #ifndef int32_t
36 | #if (LONG_MAX == 0x7fffffffL)
37 | typedef signed long int32_t;
38 | #elif (INT_MAX == 0x7fffffffL)
39 | typedef signed int int32_t;
40 | #elif (SHRT_MAX == 0x7fffffffL)
41 | typedef signed short int32_t;
42 | #endif
43 | #endif
44 |
45 |
46 | /* (u)int64_t */
47 | #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L)
48 | typedef long long int64_t;
49 | typedef unsigned long long uint64_t;
50 |
51 | #define UINT64_C(v) v ##ULL
52 | #define INT64_C(v) v ##LL
53 | #elif defined(__GNUC__)
54 | __extension__ typedef long long int64_t;
55 | __extension__ typedef unsigned long long uint64_t;
56 |
57 | #define UINT64_C(v) v ##ULL
58 | #define INT64_C(v) v ##LL
59 | #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC)
60 | typedef long long int64_t;
61 | typedef unsigned long long uint64_t;
62 |
63 | #define UINT64_C(v) v ##ULL
64 | #define INT64_C(v) v ##LL
65 | #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC)
66 | typedef __int64 int64_t;
67 | typedef unsigned __int64 uint64_t;
68 |
69 | #define UINT64_C(v) v ##UI64
70 | #define INT64_C(v) v ##I64
71 | #endif
72 | #endif
73 |
--------------------------------------------------------------------------------
/src/lib/ed25519/ge.h:
--------------------------------------------------------------------------------
1 | #ifndef GE_H
2 | #define GE_H
3 |
4 | #include "fe.h"
5 |
6 |
7 | /*
8 | ge means group element.
9 |
10 | Here the group is the set of pairs (x,y) of field elements (see fe.h)
11 | satisfying -x^2 + y^2 = 1 + d x^2y^2
12 | where d = -121665/121666.
13 |
14 | Representations:
15 | ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
16 | ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
17 | ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
18 | ge_precomp (Duif): (y+x,y-x,2dxy)
19 | */
20 |
21 | typedef struct {
22 | fe X;
23 | fe Y;
24 | fe Z;
25 | } ge_p2;
26 |
27 | typedef struct {
28 | fe X;
29 | fe Y;
30 | fe Z;
31 | fe T;
32 | } ge_p3;
33 |
34 | typedef struct {
35 | fe X;
36 | fe Y;
37 | fe Z;
38 | fe T;
39 | } ge_p1p1;
40 |
41 | typedef struct {
42 | fe yplusx;
43 | fe yminusx;
44 | fe xy2d;
45 | } ge_precomp;
46 |
47 | typedef struct {
48 | fe YplusX;
49 | fe YminusX;
50 | fe Z;
51 | fe T2d;
52 | } ge_cached;
53 |
54 | void ge_p3_tobytes(unsigned char *s, const ge_p3 *h);
55 | void ge_tobytes(unsigned char *s, const ge_p2 *h);
56 | int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s);
57 |
58 | void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
59 | void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
60 | void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b);
61 | void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q);
62 | void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q);
63 | void ge_scalarmult_base(ge_p3 *h, const unsigned char *a);
64 |
65 | void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p);
66 | void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p);
67 | void ge_p2_0(ge_p2 *h);
68 | void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p);
69 | void ge_p3_0(ge_p3 *h);
70 | void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p);
71 | void ge_p3_to_cached(ge_cached *r, const ge_p3 *p);
72 | void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p);
73 |
74 | #endif
75 |
--------------------------------------------------------------------------------
/src/lib/ed25519/key_exchange.c:
--------------------------------------------------------------------------------
1 | #include "ed25519.h"
2 | #include "fe.h"
3 |
4 | void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) {
5 | unsigned char e[32];
6 | unsigned int i;
7 |
8 | fe x1;
9 | fe x2;
10 | fe z2;
11 | fe x3;
12 | fe z3;
13 | fe tmp0;
14 | fe tmp1;
15 |
16 | int pos;
17 | unsigned int swap;
18 | unsigned int b;
19 |
20 | /* copy the private key and make sure it's valid */
21 | for (i = 0; i < 32; ++i) {
22 | e[i] = private_key[i];
23 | }
24 |
25 | e[0] &= 248;
26 | e[31] &= 63;
27 | e[31] |= 64;
28 |
29 | /* unpack the public key and convert edwards to montgomery */
30 | /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
31 | fe_frombytes(x1, public_key);
32 | fe_1(tmp1);
33 | fe_add(tmp0, x1, tmp1);
34 | fe_sub(tmp1, tmp1, x1);
35 | fe_invert(tmp1, tmp1);
36 | fe_mul(x1, tmp0, tmp1);
37 |
38 | fe_1(x2);
39 | fe_0(z2);
40 | fe_copy(x3, x1);
41 | fe_1(z3);
42 |
43 | swap = 0;
44 | for (pos = 254; pos >= 0; --pos) {
45 | b = e[pos / 8] >> (pos & 7);
46 | b &= 1;
47 | swap ^= b;
48 | fe_cswap(x2, x3, swap);
49 | fe_cswap(z2, z3, swap);
50 | swap = b;
51 |
52 | /* from montgomery.h */
53 | fe_sub(tmp0, x3, z3);
54 | fe_sub(tmp1, x2, z2);
55 | fe_add(x2, x2, z2);
56 | fe_add(z2, x3, z3);
57 | fe_mul(z3, tmp0, x2);
58 | fe_mul(z2, z2, tmp1);
59 | fe_sq(tmp0, tmp1);
60 | fe_sq(tmp1, x2);
61 | fe_add(x3, z3, z2);
62 | fe_sub(z2, z3, z2);
63 | fe_mul(x2, tmp1, tmp0);
64 | fe_sub(tmp1, tmp1, tmp0);
65 | fe_sq(z2, z2);
66 | fe_mul121666(z3, tmp1);
67 | fe_sq(x3, x3);
68 | fe_add(tmp0, tmp0, z3);
69 | fe_mul(z3, x1, z2);
70 | fe_mul(z2, tmp1, tmp0);
71 | }
72 |
73 | fe_cswap(x2, x3, swap);
74 | fe_cswap(z2, z3, swap);
75 |
76 | fe_invert(z2, z2);
77 | fe_mul(x2, x2, z2);
78 | fe_tobytes(shared_secret, x2);
79 | }
80 |
--------------------------------------------------------------------------------
/src/lib/ed25519/keypair.c:
--------------------------------------------------------------------------------
1 | #include "ed25519.h"
2 | #include "sha512.h"
3 | #include "ge.h"
4 |
5 |
6 | void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
7 | ge_p3 A;
8 |
9 | sha512(seed, 32, private_key);
10 | private_key[0] &= 248;
11 | private_key[31] &= 63;
12 | private_key[31] |= 64;
13 |
14 | ge_scalarmult_base(&A, private_key);
15 | ge_p3_tobytes(public_key, &A);
16 | }
17 |
--------------------------------------------------------------------------------
/src/lib/ed25519/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 Orson Peters
2 |
3 | This software is provided 'as-is', without any express or implied warranty. In no event will the
4 | authors be held liable for any damages arising from the use of this software.
5 |
6 | Permission is granted to anyone to use this software for any purpose, including commercial
7 | applications, and to alter it and redistribute it freely, subject to the following restrictions:
8 |
9 | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the
10 | original software. If you use this software in a product, an acknowledgment in the product
11 | documentation would be appreciated but is not required.
12 |
13 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as
14 | being the original software.
15 |
16 | 3. This notice may not be removed or altered from any source distribution.
17 |
--------------------------------------------------------------------------------
/src/lib/ed25519/sc.h:
--------------------------------------------------------------------------------
1 | #ifndef SC_H
2 | #define SC_H
3 |
4 | /*
5 | The set of scalars is \Z/l
6 | where l = 2^252 + 27742317777372353535851937790883648493.
7 | */
8 |
9 | void sc_reduce(unsigned char *s);
10 | void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c);
11 |
12 | #endif
13 |
--------------------------------------------------------------------------------
/src/lib/ed25519/seed.c:
--------------------------------------------------------------------------------
1 | #include "ed25519.h"
2 |
3 | #ifndef ED25519_NO_SEED
4 |
5 | #ifdef _WIN32
6 | #include
7 | #include
8 | #else
9 | #include
10 | #endif
11 |
12 | int ed25519_create_seed(unsigned char *seed) {
13 | #ifdef _WIN32
14 | HCRYPTPROV prov;
15 |
16 | if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
17 | return 1;
18 | }
19 |
20 | if (!CryptGenRandom(prov, 32, seed)) {
21 | CryptReleaseContext(prov, 0);
22 | return 1;
23 | }
24 |
25 | CryptReleaseContext(prov, 0);
26 | #else
27 | FILE *f = fopen("/dev/urandom", "rb");
28 |
29 | if (f == NULL) {
30 | return 1;
31 | }
32 |
33 | fread(seed, 1, 32, f);
34 | fclose(f);
35 | #endif
36 |
37 | return 0;
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/src/lib/ed25519/sha512.h:
--------------------------------------------------------------------------------
1 | #ifndef SHA512_H
2 | #define SHA512_H
3 |
4 | #include
5 |
6 | #include "fixedint.h"
7 |
8 | /* state */
9 | typedef struct sha512_context_ {
10 | uint64_t length, state[8];
11 | size_t curlen;
12 | unsigned char buf[128];
13 | } sha512_context;
14 |
15 |
16 | int sha512_init(sha512_context * md);
17 | int sha512_final(sha512_context * md, unsigned char *out);
18 | int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen);
19 | int sha512(const unsigned char *message, size_t message_len, unsigned char *out);
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/src/lib/ed25519/sign.c:
--------------------------------------------------------------------------------
1 | #include "ed25519.h"
2 | #include "sha512.h"
3 | #include "ge.h"
4 | #include "sc.h"
5 |
6 |
7 | void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
8 | sha512_context hash;
9 | unsigned char hram[64];
10 | unsigned char r[64];
11 | ge_p3 R;
12 |
13 |
14 | sha512_init(&hash);
15 | sha512_update(&hash, private_key + 32, 32);
16 | sha512_update(&hash, message, message_len);
17 | sha512_final(&hash, r);
18 |
19 | sc_reduce(r);
20 | ge_scalarmult_base(&R, r);
21 | ge_p3_tobytes(signature, &R);
22 |
23 | sha512_init(&hash);
24 | sha512_update(&hash, signature, 32);
25 | sha512_update(&hash, public_key, 32);
26 | sha512_update(&hash, message, message_len);
27 | sha512_final(&hash, hram);
28 |
29 | sc_reduce(hram);
30 | sc_muladd(signature + 32, hram, private_key, r);
31 | }
32 |
--------------------------------------------------------------------------------
/src/lib/ed25519/verify.c:
--------------------------------------------------------------------------------
1 | #include "ed25519.h"
2 | #include "sha512.h"
3 | #include "ge.h"
4 | #include "sc.h"
5 |
6 | static int consttime_equal(const unsigned char *x, const unsigned char *y) {
7 | unsigned char r = 0;
8 |
9 | r = x[0] ^ y[0];
10 | #define F(i) r |= x[i] ^ y[i]
11 | F(1);
12 | F(2);
13 | F(3);
14 | F(4);
15 | F(5);
16 | F(6);
17 | F(7);
18 | F(8);
19 | F(9);
20 | F(10);
21 | F(11);
22 | F(12);
23 | F(13);
24 | F(14);
25 | F(15);
26 | F(16);
27 | F(17);
28 | F(18);
29 | F(19);
30 | F(20);
31 | F(21);
32 | F(22);
33 | F(23);
34 | F(24);
35 | F(25);
36 | F(26);
37 | F(27);
38 | F(28);
39 | F(29);
40 | F(30);
41 | F(31);
42 | #undef F
43 |
44 | return !r;
45 | }
46 |
47 | int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
48 | unsigned char h[64];
49 | unsigned char checker[32];
50 | sha512_context hash;
51 | ge_p3 A;
52 | ge_p2 R;
53 |
54 | if (signature[63] & 224) {
55 | return 0;
56 | }
57 |
58 | if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
59 | return 0;
60 | }
61 |
62 | sha512_init(&hash);
63 | sha512_update(&hash, signature, 32);
64 | sha512_update(&hash, public_key, 32);
65 | sha512_update(&hash, message, message_len);
66 | sha512_final(&hash, h);
67 |
68 | sc_reduce(h);
69 | ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
70 | ge_tobytes(checker, &R);
71 |
72 | if (!consttime_equal(checker, signature)) {
73 | return 0;
74 | }
75 |
76 | return 1;
77 | }
78 |
--------------------------------------------------------------------------------
/src/lib/fairplay.h:
--------------------------------------------------------------------------------
1 | #ifndef FAIRPLAY_H
2 | #define FAIRPLAY_H
3 |
4 | #include "logger.h"
5 |
6 | typedef struct fairplay_s fairplay_t;
7 |
8 | fairplay_t *fairplay_init(logger_t *logger);
9 | int fairplay_setup(fairplay_t *fp, const unsigned char req[16], unsigned char res[142]);
10 | int fairplay_handshake(fairplay_t *fp, const unsigned char req[164], unsigned char res[32]);
11 | int fairplay_decrypt(fairplay_t *fp, const unsigned char input[72], unsigned char output[16]);
12 | void fairplay_destroy(fairplay_t *fp);
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/src/lib/fairplay_dummy.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "fairplay.h"
4 |
5 | struct fairplay_s {
6 | };
7 |
8 | fairplay_t *
9 | fairplay_init(logger_t *logger)
10 | {
11 | /* NULL would mean failure so let's use any number */
12 | return (void *) 42;
13 | }
14 |
15 | int
16 | fairplay_setup(fairplay_t *fp, const unsigned char req[16], unsigned char res[142])
17 | {
18 | return -1;
19 | }
20 |
21 | int
22 | fairplay_handshake(fairplay_t *fp, const unsigned char req[164], unsigned char res[32])
23 | {
24 | return -1;
25 | }
26 |
27 | int
28 | fairplay_decrypt(fairplay_t *fp, const unsigned char input[72], unsigned char output[16])
29 | {
30 | return -1;
31 | }
32 |
33 | void
34 | fairplay_destroy(fairplay_t *fp)
35 | {
36 | }
37 |
--------------------------------------------------------------------------------
/src/lib/fairplay_playfair.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "fairplay.h"
6 | #include "playfair/playfair.h"
7 |
8 | char reply_message[4][142] = {{0x46,0x50,0x4c,0x59,0x03,0x01,0x02,0x00,0x00,0x00,0x00,0x82,0x02,0x00,0x0f,0x9f,0x3f,0x9e,0x0a,0x25,0x21,0xdb,0xdf,0x31,0x2a,0xb2,0xbf,0xb2,0x9e,0x8d,0x23,0x2b,0x63,0x76,0xa8,0xc8,0x18,0x70,0x1d,0x22,0xae,0x93,0xd8,0x27,0x37,0xfe,0xaf,0x9d,0xb4,0xfd,0xf4,0x1c,0x2d,0xba,0x9d,0x1f,0x49,0xca,0xaa,0xbf,0x65,0x91,0xac,0x1f,0x7b,0xc6,0xf7,0xe0,0x66,0x3d,0x21,0xaf,0xe0,0x15,0x65,0x95,0x3e,0xab,0x81,0xf4,0x18,0xce,0xed,0x09,0x5a,0xdb,0x7c,0x3d,0x0e,0x25,0x49,0x09,0xa7,0x98,0x31,0xd4,0x9c,0x39,0x82,0x97,0x34,0x34,0xfa,0xcb,0x42,0xc6,0x3a,0x1c,0xd9,0x11,0xa6,0xfe,0x94,0x1a,0x8a,0x6d,0x4a,0x74,0x3b,0x46,0xc3,0xa7,0x64,0x9e,0x44,0xc7,0x89,0x55,0xe4,0x9d,0x81,0x55,0x00,0x95,0x49,0xc4,0xe2,0xf7,0xa3,0xf6,0xd5,0xba},
9 | {0x46,0x50,0x4c,0x59,0x03,0x01,0x02,0x00,0x00,0x00,0x00,0x82,0x02,0x01,0xcf,0x32,0xa2,0x57,0x14,0xb2,0x52,0x4f,0x8a,0xa0,0xad,0x7a,0xf1,0x64,0xe3,0x7b,0xcf,0x44,0x24,0xe2,0x00,0x04,0x7e,0xfc,0x0a,0xd6,0x7a,0xfc,0xd9,0x5d,0xed,0x1c,0x27,0x30,0xbb,0x59,0x1b,0x96,0x2e,0xd6,0x3a,0x9c,0x4d,0xed,0x88,0xba,0x8f,0xc7,0x8d,0xe6,0x4d,0x91,0xcc,0xfd,0x5c,0x7b,0x56,0xda,0x88,0xe3,0x1f,0x5c,0xce,0xaf,0xc7,0x43,0x19,0x95,0xa0,0x16,0x65,0xa5,0x4e,0x19,0x39,0xd2,0x5b,0x94,0xdb,0x64,0xb9,0xe4,0x5d,0x8d,0x06,0x3e,0x1e,0x6a,0xf0,0x7e,0x96,0x56,0x16,0x2b,0x0e,0xfa,0x40,0x42,0x75,0xea,0x5a,0x44,0xd9,0x59,0x1c,0x72,0x56,0xb9,0xfb,0xe6,0x51,0x38,0x98,0xb8,0x02,0x27,0x72,0x19,0x88,0x57,0x16,0x50,0x94,0x2a,0xd9,0x46,0x68,0x8a},
10 | {0x46,0x50,0x4c,0x59,0x03,0x01,0x02,0x00,0x00,0x00,0x00,0x82,0x02,0x02,0xc1,0x69,0xa3,0x52,0xee,0xed,0x35,0xb1,0x8c,0xdd,0x9c,0x58,0xd6,0x4f,0x16,0xc1,0x51,0x9a,0x89,0xeb,0x53,0x17,0xbd,0x0d,0x43,0x36,0xcd,0x68,0xf6,0x38,0xff,0x9d,0x01,0x6a,0x5b,0x52,0xb7,0xfa,0x92,0x16,0xb2,0xb6,0x54,0x82,0xc7,0x84,0x44,0x11,0x81,0x21,0xa2,0xc7,0xfe,0xd8,0x3d,0xb7,0x11,0x9e,0x91,0x82,0xaa,0xd7,0xd1,0x8c,0x70,0x63,0xe2,0xa4,0x57,0x55,0x59,0x10,0xaf,0x9e,0x0e,0xfc,0x76,0x34,0x7d,0x16,0x40,0x43,0x80,0x7f,0x58,0x1e,0xe4,0xfb,0xe4,0x2c,0xa9,0xde,0xdc,0x1b,0x5e,0xb2,0xa3,0xaa,0x3d,0x2e,0xcd,0x59,0xe7,0xee,0xe7,0x0b,0x36,0x29,0xf2,0x2a,0xfd,0x16,0x1d,0x87,0x73,0x53,0xdd,0xb9,0x9a,0xdc,0x8e,0x07,0x00,0x6e,0x56,0xf8,0x50,0xce},
11 | {0x46,0x50,0x4c,0x59,0x03,0x01,0x02,0x00,0x00,0x00,0x00,0x82,0x02,0x03,0x90,0x01,0xe1,0x72,0x7e,0x0f,0x57,0xf9,0xf5,0x88,0x0d,0xb1,0x04,0xa6,0x25,0x7a,0x23,0xf5,0xcf,0xff,0x1a,0xbb,0xe1,0xe9,0x30,0x45,0x25,0x1a,0xfb,0x97,0xeb,0x9f,0xc0,0x01,0x1e,0xbe,0x0f,0x3a,0x81,0xdf,0x5b,0x69,0x1d,0x76,0xac,0xb2,0xf7,0xa5,0xc7,0x08,0xe3,0xd3,0x28,0xf5,0x6b,0xb3,0x9d,0xbd,0xe5,0xf2,0x9c,0x8a,0x17,0xf4,0x81,0x48,0x7e,0x3a,0xe8,0x63,0xc6,0x78,0x32,0x54,0x22,0xe6,0xf7,0x8e,0x16,0x6d,0x18,0xaa,0x7f,0xd6,0x36,0x25,0x8b,0xce,0x28,0x72,0x6f,0x66,0x1f,0x73,0x88,0x93,0xce,0x44,0x31,0x1e,0x4b,0xe6,0xc0,0x53,0x51,0x93,0xe5,0xef,0x72,0xe8,0x68,0x62,0x33,0x72,0x9c,0x22,0x7d,0x82,0x0c,0x99,0x94,0x45,0xd8,0x92,0x46,0xc8,0xc3,0x59}};
12 |
13 | char fp_header[] = {0x46, 0x50, 0x4c, 0x59, 0x03, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14};
14 |
15 | struct fairplay_s {
16 | logger_t *logger;
17 |
18 | unsigned char keymsg[164];
19 | unsigned int keymsglen;
20 | };
21 |
22 | fairplay_t *
23 | fairplay_init(logger_t *logger)
24 | {
25 | fairplay_t *fp;
26 |
27 | fp = calloc(1, sizeof(fairplay_t));
28 | if (!fp) {
29 | return NULL;
30 | }
31 | fp->logger = logger;
32 |
33 | return fp;
34 | }
35 |
36 | int
37 | fairplay_setup(fairplay_t *fp, const unsigned char req[16], unsigned char res[142])
38 | {
39 | int mode;
40 |
41 | assert(fp);
42 |
43 | if (req[4] != 0x03) {
44 | /* Unsupported fairplay version */
45 | return -1;
46 | }
47 |
48 | mode = req[14];
49 | memcpy(res, reply_message[mode], 142);
50 | fp->keymsglen = 0;
51 | return 0;
52 | }
53 |
54 | int
55 | fairplay_handshake(fairplay_t *fp, const unsigned char req[164], unsigned char res[32])
56 | {
57 | assert(fp);
58 |
59 | if (req[4] != 0x03) {
60 | /* Unsupported fairplay version */
61 | return -1;
62 | }
63 |
64 | memcpy(fp->keymsg, req, 164);
65 | fp->keymsglen = 164;
66 |
67 | memcpy(res, fp_header, 12);
68 | memcpy(res + 12, req + 144, 20);
69 | return 0;
70 | }
71 |
72 | int
73 | fairplay_decrypt(fairplay_t *fp, const unsigned char input[72], unsigned char output[16])
74 | {
75 | if (fp->keymsglen != 164) {
76 | return -1;
77 | }
78 |
79 | playfair_decrypt(fp->keymsg, (unsigned char *) input, output);
80 | return 0;
81 | }
82 |
83 | void
84 | fairplay_destroy(fairplay_t *fp)
85 | {
86 | free(fp);
87 | }
88 |
--------------------------------------------------------------------------------
/src/lib/global.h:
--------------------------------------------------------------------------------
1 | #ifndef GLOBAL_H
2 | #define GLOBAL_H
3 |
4 | #define GLOBAL_FEATURES 0x7
5 | #define GLOBAL_MODEL "AppleTV2,1"
6 | #define GLOBAL_VERSION "130.14"
7 |
8 | #define MAX_HWADDR_LEN 6
9 |
10 | #endif
11 |
--------------------------------------------------------------------------------
/src/lib/http_request.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef HTTP_REQUEST_H
16 | #define HTTP_REQUEST_H
17 |
18 | typedef struct http_request_s http_request_t;
19 |
20 |
21 | http_request_t *http_request_init(void);
22 |
23 | int http_request_add_data(http_request_t *request, const char *data, int datalen);
24 | int http_request_is_complete(http_request_t *request);
25 | int http_request_has_error(http_request_t *request);
26 |
27 | const char *http_request_get_error_name(http_request_t *request);
28 | const char *http_request_get_error_description(http_request_t *request);
29 | const char *http_request_get_method(http_request_t *request);
30 | const char *http_request_get_url(http_request_t *request);
31 | const char *http_request_get_header(http_request_t *request, const char *name);
32 | const char *http_request_get_data(http_request_t *request, int *datalen);
33 |
34 | void http_request_destroy(http_request_t *request);
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/src/lib/http_response.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "http_response.h"
21 | #include "compat.h"
22 |
23 | struct http_response_s {
24 | int complete;
25 | int disconnect;
26 |
27 | char *data;
28 | int data_size;
29 | int data_length;
30 | };
31 |
32 |
33 | static void
34 | http_response_add_data(http_response_t *response, const char *data, int datalen)
35 | {
36 | int newdatasize;
37 |
38 | assert(response);
39 | assert(data);
40 | assert(datalen > 0);
41 |
42 | newdatasize = response->data_size;
43 | while (response->data_size+datalen > newdatasize) {
44 | newdatasize *= 2;
45 | }
46 | if (newdatasize != response->data_size) {
47 | response->data = realloc(response->data, newdatasize);
48 | assert(response->data);
49 | }
50 | memcpy(response->data+response->data_length, data, datalen);
51 | response->data_length += datalen;
52 | }
53 |
54 | http_response_t *
55 | http_response_init(const char *protocol, int code, const char *message)
56 | {
57 | http_response_t *response;
58 | char codestr[4];
59 |
60 | assert(code >= 100 && code < 1000);
61 |
62 | /* Convert code into string */
63 | memset(codestr, 0, sizeof(codestr));
64 | snprintf(codestr, sizeof(codestr), "%u", code);
65 |
66 | response = calloc(1, sizeof(http_response_t));
67 | if (!response) {
68 | return NULL;
69 | }
70 |
71 | /* Allocate response data */
72 | response->data_size = 1024;
73 | response->data = malloc(response->data_size);
74 | if (!response->data) {
75 | free(response);
76 | return NULL;
77 | }
78 |
79 | /* Add first line of response to the data array */
80 | http_response_add_data(response, protocol, strlen(protocol));
81 | http_response_add_data(response, " ", 1);
82 | http_response_add_data(response, codestr, strlen(codestr));
83 | http_response_add_data(response, " ", 1);
84 | http_response_add_data(response, message, strlen(message));
85 | http_response_add_data(response, "\r\n", 2);
86 |
87 | return response;
88 | }
89 |
90 | void
91 | http_response_destroy(http_response_t *response)
92 | {
93 | if (response) {
94 | free(response->data);
95 | free(response);
96 | }
97 | }
98 |
99 | void
100 | http_response_add_header(http_response_t *response, const char *name, const char *value)
101 | {
102 | assert(response);
103 | assert(name);
104 | assert(value);
105 |
106 | http_response_add_data(response, name, strlen(name));
107 | http_response_add_data(response, ": ", 2);
108 | http_response_add_data(response, value, strlen(value));
109 | http_response_add_data(response, "\r\n", 2);
110 | }
111 |
112 | void
113 | http_response_finish(http_response_t *response, const char *data, int datalen)
114 | {
115 | assert(response);
116 | assert(datalen==0 || (data && datalen > 0));
117 |
118 | if (data && datalen > 0) {
119 | const char *hdrname = "Content-Length";
120 | char hdrvalue[16];
121 |
122 | memset(hdrvalue, 0, sizeof(hdrvalue));
123 | snprintf(hdrvalue, sizeof(hdrvalue)-1, "%d", datalen);
124 |
125 | /* Add Content-Length header first */
126 | http_response_add_data(response, hdrname, strlen(hdrname));
127 | http_response_add_data(response, ": ", 2);
128 | http_response_add_data(response, hdrvalue, strlen(hdrvalue));
129 | http_response_add_data(response, "\r\n\r\n", 4);
130 |
131 | /* Add data to the end of response */
132 | http_response_add_data(response, data, datalen);
133 | } else {
134 | /* Add extra end of line after headers */
135 | http_response_add_data(response, "\r\n", 2);
136 | }
137 | response->complete = 1;
138 | }
139 |
140 | void
141 | http_response_set_disconnect(http_response_t *response, int disconnect)
142 | {
143 | assert(response);
144 |
145 | response->disconnect = !!disconnect;
146 | }
147 |
148 | int
149 | http_response_get_disconnect(http_response_t *response)
150 | {
151 | assert(response);
152 |
153 | return response->disconnect;
154 | }
155 |
156 | const char *
157 | http_response_get_data(http_response_t *response, int *datalen)
158 | {
159 | assert(response);
160 | assert(datalen);
161 | assert(response->complete);
162 |
163 | *datalen = response->data_length;
164 | return response->data;
165 | }
166 |
--------------------------------------------------------------------------------
/src/lib/http_response.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef HTTP_RESPONSE_H
16 | #define HTTP_RESPONSE_H
17 |
18 | typedef struct http_response_s http_response_t;
19 |
20 | http_response_t *http_response_init(const char *protocol, int code, const char *message);
21 |
22 | void http_response_add_header(http_response_t *response, const char *name, const char *value);
23 | void http_response_finish(http_response_t *response, const char *data, int datalen);
24 |
25 | void http_response_set_disconnect(http_response_t *response, int disconnect);
26 | int http_response_get_disconnect(http_response_t *response);
27 |
28 | const char *http_response_get_data(http_response_t *response, int *datalen);
29 |
30 | void http_response_destroy(http_response_t *response);
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/src/lib/httpd.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef HTTPD_H
16 | #define HTTPD_H
17 |
18 | #include "logger.h"
19 | #include "http_request.h"
20 | #include "http_response.h"
21 |
22 | typedef struct httpd_s httpd_t;
23 |
24 | struct httpd_callbacks_s {
25 | void* opaque;
26 | void* (*conn_init)(void *opaque, unsigned char *local, int locallen, unsigned char *remote, int remotelen);
27 | void (*conn_request)(void *ptr, http_request_t *request, http_response_t **response);
28 | void (*conn_destroy)(void *ptr);
29 | };
30 | typedef struct httpd_callbacks_s httpd_callbacks_t;
31 |
32 |
33 | httpd_t *httpd_init(logger_t *logger, httpd_callbacks_t *callbacks, int max_connections);
34 |
35 | int httpd_is_running(httpd_t *httpd);
36 |
37 | int httpd_start(httpd_t *httpd, unsigned short *port);
38 | void httpd_stop(httpd_t *httpd);
39 |
40 | void httpd_destroy(httpd_t *httpd);
41 |
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/src/lib/logger.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "logger.h"
21 | #include "compat.h"
22 |
23 | struct logger_s {
24 | mutex_handle_t lvl_mutex;
25 | mutex_handle_t cb_mutex;
26 |
27 | int level;
28 | void *cls;
29 | logger_callback_t callback;
30 | };
31 |
32 | logger_t *
33 | logger_init()
34 | {
35 | logger_t *logger = calloc(1, sizeof(logger_t));
36 | assert(logger);
37 |
38 | MUTEX_CREATE(logger->lvl_mutex);
39 | MUTEX_CREATE(logger->cb_mutex);
40 |
41 | logger->level = LOGGER_WARNING;
42 | logger->callback = NULL;
43 | return logger;
44 | }
45 |
46 | void
47 | logger_destroy(logger_t *logger)
48 | {
49 | MUTEX_DESTROY(logger->lvl_mutex);
50 | MUTEX_DESTROY(logger->cb_mutex);
51 | free(logger);
52 | }
53 |
54 | void
55 | logger_set_level(logger_t *logger, int level)
56 | {
57 | assert(logger);
58 |
59 | MUTEX_LOCK(logger->lvl_mutex);
60 | logger->level = level;
61 | MUTEX_UNLOCK(logger->lvl_mutex);
62 | }
63 |
64 | void
65 | logger_set_callback(logger_t *logger, logger_callback_t callback, void *cls)
66 | {
67 | assert(logger);
68 |
69 | MUTEX_LOCK(logger->cb_mutex);
70 | logger->cls = cls;
71 | logger->callback = callback;
72 | MUTEX_UNLOCK(logger->cb_mutex);
73 | }
74 |
75 | static char *
76 | logger_utf8_to_local(const char *str)
77 | {
78 | char *ret = NULL;
79 |
80 | /* FIXME: This is only implemented on Windows for now */
81 | #if defined(_WIN32) || defined(_WIN64)
82 | int wclen, mblen;
83 | WCHAR *wcstr;
84 | BOOL failed;
85 |
86 | wclen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
87 | wcstr = malloc(sizeof(WCHAR) * wclen);
88 | MultiByteToWideChar(CP_UTF8, 0, str, -1, wcstr, wclen);
89 |
90 | mblen = WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, NULL, 0, NULL, &failed);
91 | if (failed) {
92 | /* Invalid characters in input, conversion failed */
93 | free(wcstr);
94 | return NULL;
95 | }
96 |
97 | ret = malloc(sizeof(CHAR) * mblen);
98 | WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, ret, mblen, NULL, NULL);
99 | free(wcstr);
100 | #endif
101 |
102 | return ret;
103 | }
104 |
105 | void
106 | logger_log(logger_t *logger, int level, const char *fmt, ...)
107 | {
108 | char buffer[4096];
109 | va_list ap;
110 |
111 | MUTEX_LOCK(logger->lvl_mutex);
112 | if (level > logger->level) {
113 | MUTEX_UNLOCK(logger->lvl_mutex);
114 | return;
115 | }
116 | MUTEX_UNLOCK(logger->lvl_mutex);
117 |
118 | buffer[sizeof(buffer)-1] = '\0';
119 | va_start(ap, fmt);
120 | vsnprintf(buffer, sizeof(buffer)-1, fmt, ap);
121 | va_end(ap);
122 |
123 | MUTEX_LOCK(logger->cb_mutex);
124 | if (logger->callback) {
125 | logger->callback(logger->cls, level, buffer);
126 | MUTEX_UNLOCK(logger->cb_mutex);
127 | } else {
128 | char *local;
129 | MUTEX_UNLOCK(logger->cb_mutex);
130 | local = logger_utf8_to_local(buffer);
131 | if (local) {
132 | fprintf(stderr, "%s\n", local);
133 | free(local);
134 | } else {
135 | fprintf(stderr, "%s\n", buffer);
136 | }
137 | }
138 | }
139 |
140 |
--------------------------------------------------------------------------------
/src/lib/logger.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef LOGGER_H
16 | #define LOGGER_H
17 |
18 | /* Define syslog style log levels */
19 | #define LOGGER_EMERG 0 /* system is unusable */
20 | #define LOGGER_ALERT 1 /* action must be taken immediately */
21 | #define LOGGER_CRIT 2 /* critical conditions */
22 | #define LOGGER_ERR 3 /* error conditions */
23 | #define LOGGER_WARNING 4 /* warning conditions */
24 | #define LOGGER_NOTICE 5 /* normal but significant condition */
25 | #define LOGGER_INFO 6 /* informational */
26 | #define LOGGER_DEBUG 7 /* debug-level messages */
27 |
28 | typedef void (*logger_callback_t)(void *cls, int level, const char *msg);
29 |
30 | typedef struct logger_s logger_t;
31 |
32 | logger_t *logger_init();
33 | void logger_destroy(logger_t *logger);
34 |
35 | void logger_set_level(logger_t *logger, int level);
36 | void logger_set_callback(logger_t *logger, logger_callback_t callback, void *cls);
37 |
38 | void logger_log(logger_t *logger, int level, const char *fmt, ...);
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/src/lib/memalign.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef MEMALIGN_H
16 | #define MEMALIGN_H
17 |
18 | #if defined(WIN32)
19 |
20 | #define SYSTEM_GET_PAGESIZE(ret) do {\
21 | SYSTEM_INFO si;\
22 | GetSystemInfo(&si);\
23 | ret = si.dwPageSize;\
24 | } while(0)
25 | #define SYSTEM_GET_TIME(ret) ret = timeGetTime()
26 |
27 | #define ALIGNED_MALLOC(memptr, alignment, size) do {\
28 | char *ptr = malloc(sizeof(void*) + (size) + (alignment)-1);\
29 | memptr = NULL;\
30 | if (ptr) {\
31 | size_t ptrval = (size_t)ptr + sizeof(void*) + (alignment)-1;\
32 | ptrval = ptrval / (alignment) * (alignment);\
33 | memptr = (void *)ptrval;\
34 | *(((void **)memptr)-1) = ptr;\
35 | }\
36 | } while(0)
37 | #define ALIGNED_FREE(memptr) free(*(((void **)memptr)-1))
38 |
39 | #else
40 |
41 | #define SYSTEM_GET_PAGESIZE(ret) ret = sysconf(_SC_PAGESIZE)
42 | #define SYSTEM_GET_TIME(ret) do {\
43 | struct timeval tv;\
44 | gettimeofday(&tv, NULL);\
45 | ret = (unsigned int)(tv.tv_sec*1000 + tv.tv_usec/1000);\
46 | } while(0)
47 |
48 | #define ALIGNED_MALLOC(memptr, alignment, size) if (posix_memalign((void **)&memptr, alignment, size)) memptr = NULL
49 | #define ALIGNED_FREE(memptr) free(memptr)
50 |
51 | #endif
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/src/lib/netutils.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef NETUTILS_H
16 | #define NETUTILS_H
17 |
18 | int netutils_init();
19 | void netutils_cleanup();
20 |
21 | int netutils_init_socket(unsigned short *port, int use_ipv6, int use_udp);
22 | unsigned char *netutils_get_address(void *sockaddr, int *length);
23 | int netutils_parse_address(int family, const char *src, void *dst, int dstlen);
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/src/lib/pairing.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2018 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef PAIRING_H
16 | #define PAIRING_H
17 |
18 | typedef struct pairing_s pairing_t;
19 | typedef struct pairing_session_s pairing_session_t;
20 |
21 | pairing_t *pairing_init_generate();
22 | pairing_t *pairing_init_seed(const unsigned char seed[32]);
23 | void pairing_get_public_key(pairing_t *pairing, unsigned char public_key[32]);
24 |
25 | pairing_session_t *pairing_session_init(pairing_t *pairing);
26 | int pairing_session_handshake(pairing_session_t *session, const unsigned char ecdh_key[32], const unsigned char ed_key[32]);
27 | int pairing_session_get_public_key(pairing_session_t *session, unsigned char ecdh_key[32]);
28 | int pairing_session_get_signature(pairing_session_t *session, unsigned char signature[64]);
29 | int pairing_session_finish(pairing_session_t *session, const unsigned char signature[64]);
30 | int pairing_session_derive_key(pairing_session_t *session, const unsigned char *seed, unsigned int seedlen, unsigned char *buf, unsigned int buflen);
31 | void pairing_session_destroy(pairing_session_t *session);
32 |
33 | void pairing_destroy(pairing_t *pairing);
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/src/lib/playfair/Makefile.am:
--------------------------------------------------------------------------------
1 | noinst_LTLIBRARIES = libplayfair.la
2 | libplayfair_la_SOURCES = playfair.c playfair.h omg_hax.c omg_hax.h hand_garble.c modified_md5.c sap_hash.c
3 |
--------------------------------------------------------------------------------
/src/lib/playfair/modified_md5.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #define printf(...) (void)0;
8 |
9 | int shift[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
10 | 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
11 | 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
12 | 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
13 |
14 | uint32_t F(uint32_t B, uint32_t C, uint32_t D)
15 | {
16 | return (B & C) | (~B & D);
17 | }
18 |
19 | uint32_t G(uint32_t B, uint32_t C, uint32_t D)
20 | {
21 | return (B & D) | (C & ~D);
22 | }
23 |
24 | uint32_t H(uint32_t B, uint32_t C, uint32_t D)
25 | {
26 | return B ^ C ^ D;
27 | }
28 |
29 | uint32_t I(uint32_t B, uint32_t C, uint32_t D)
30 | {
31 | return C ^ (B | ~D);
32 | }
33 |
34 |
35 | uint32_t rol(uint32_t input, int count)
36 | {
37 | return ((input << count) & 0xffffffff) | (input & 0xffffffff) >> (32-count);
38 | }
39 |
40 | void swap(uint32_t* a, uint32_t* b)
41 | {
42 | printf("%08x <-> %08x\n", *a, *b);
43 | uint32_t c = *a;
44 | *a = *b;
45 | *b = c;
46 | }
47 |
48 | void modified_md5(unsigned char* originalblockIn, unsigned char* keyIn, unsigned char* keyOut)
49 | {
50 | unsigned char blockIn[64];
51 | uint32_t* block_words = (uint32_t*)blockIn;
52 | uint32_t* key_words = (uint32_t*)keyIn;
53 | uint32_t* out_words = (uint32_t*)keyOut;
54 | uint32_t A, B, C, D, Z, tmp;
55 | int i;
56 |
57 | memcpy(blockIn, originalblockIn, 64);
58 |
59 | // Each cycle does something like this:
60 | A = key_words[0];
61 | B = key_words[1];
62 | C = key_words[2];
63 | D = key_words[3];
64 | for (i = 0; i < 64; i++)
65 | {
66 | uint32_t input;
67 | int j;
68 | if (i < 16)
69 | j = i;
70 | else if (i < 32)
71 | j = (5*i + 1) % 16;
72 | else if (i < 48)
73 | j = (3*i + 5) % 16;
74 | else if (i < 64)
75 | j = 7*i % 16;
76 |
77 | input = blockIn[4*j] << 24 | blockIn[4*j+1] << 16 | blockIn[4*j+2] << 8 | blockIn[4*j+3];
78 | printf("Key = %08x\n", A);
79 | Z = A + input + (int)(long long)((1LL << 32) * fabs(sin(i + 1)));
80 | if (i < 16)
81 | Z = rol(Z + F(B,C,D), shift[i]);
82 | else if (i < 32)
83 | Z = rol(Z + G(B,C,D), shift[i]);
84 | else if (i < 48)
85 | Z = rol(Z + H(B,C,D), shift[i]);
86 | else if (i < 64)
87 | Z = rol(Z + I(B,C,D), shift[i]);
88 | if (i == 63)
89 | printf("Ror is %08x\n", Z);
90 | printf("Output of round %d: %08X + %08X = %08X (shift %d, constant %08X)\n", i, Z, B, Z+B, shift[i], (int)(long long)((1LL << 32) * fabs(sin(i + 1))));
91 | Z = Z + B;
92 | tmp = D;
93 | D = C;
94 | C = B;
95 | B = Z;
96 | A = tmp;
97 | if (i == 31)
98 | {
99 | // swapsies
100 | swap(&block_words[A & 15], &block_words[B & 15]);
101 | swap(&block_words[C & 15], &block_words[D & 15]);
102 | swap(&block_words[(A & (15<<4))>>4], &block_words[(B & (15<<4))>>4]);
103 | swap(&block_words[(A & (15<<8))>>8], &block_words[(B & (15<<8))>>8]);
104 | swap(&block_words[(A & (15<<12))>>12], &block_words[(B & (15<<12))>>12]);
105 | }
106 | }
107 | printf("%08X %08X %08X %08X\n", A, B, C, D);
108 | // Now we can actually compute the output
109 | printf("Out:\n");
110 | printf("%08x + %08x = %08x\n", key_words[0], A, key_words[0] + A);
111 | printf("%08x + %08x = %08x\n", key_words[1], B, key_words[1] + B);
112 | printf("%08x + %08x = %08x\n", key_words[2], C, key_words[2] + C);
113 | printf("%08x + %08x = %08x\n", key_words[3], D, key_words[3] + D);
114 | out_words[0] = key_words[0] + A;
115 | out_words[1] = key_words[1] + B;
116 | out_words[2] = key_words[2] + C;
117 | out_words[3] = key_words[3] + D;
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/src/lib/playfair/playfair.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "playfair.h"
4 |
5 | void generate_key_schedule(unsigned char* key_material, uint32_t key_schedule[11][4]);
6 | void generate_session_key(unsigned char* oldSap, unsigned char* messageIn, unsigned char* sessionKey);
7 | void cycle(unsigned char* block, uint32_t key_schedule[11][4]);
8 | void z_xor(unsigned char* in, unsigned char* out, int blocks);
9 | void x_xor(unsigned char* in, unsigned char* out, int blocks);
10 |
11 | extern unsigned char default_sap[];
12 |
13 | void playfair_decrypt(unsigned char* message3, unsigned char* cipherText, unsigned char* keyOut)
14 | {
15 | unsigned char* chunk1 = &cipherText[16];
16 | unsigned char* chunk2 = &cipherText[56];
17 | int i;
18 | unsigned char blockIn[16];
19 | unsigned char sapKey[16];
20 | uint32_t key_schedule[11][4];
21 | generate_session_key(default_sap, message3, sapKey);
22 | generate_key_schedule(sapKey, key_schedule);
23 | z_xor(chunk2, blockIn, 1);
24 | cycle(blockIn, key_schedule);
25 | for (i = 0; i < 16; i++) {
26 | keyOut[i] = blockIn[i] ^ chunk1[i];
27 | }
28 | x_xor(keyOut, keyOut, 1);
29 | z_xor(keyOut, keyOut, 1);
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/src/lib/playfair/playfair.h:
--------------------------------------------------------------------------------
1 | #ifndef PLAYFAIR_H
2 | #define PLAYFAIR_H
3 |
4 | void playfair_decrypt(unsigned char* message3, unsigned char* cipherText, unsigned char* keyOut);
5 |
6 | #endif
7 |
--------------------------------------------------------------------------------
/src/lib/playfair/sap_hash.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #define printf(...) (void)0;
6 |
7 | void garble(unsigned char*, unsigned char*, unsigned char*, unsigned char*, unsigned char*);
8 |
9 | unsigned char rol8(unsigned char input, int count)
10 | {
11 | return ((input << count) & 0xff) | (input & 0xff) >> (8-count);
12 | }
13 |
14 | uint32_t rol8x(unsigned char input, int count)
15 | {
16 | return ((input << count)) | (input) >> (8-count);
17 | }
18 |
19 |
20 | void sap_hash(unsigned char* blockIn, unsigned char* keyOut)
21 | {
22 | uint32_t* block_words = (uint32_t*)blockIn;
23 | uint32_t* out_words = (uint32_t*)keyOut;
24 | unsigned char buffer0[20] = {0x96, 0x5F, 0xC6, 0x53, 0xF8, 0x46, 0xCC, 0x18, 0xDF, 0xBE, 0xB2, 0xF8, 0x38, 0xD7, 0xEC, 0x22, 0x03, 0xD1, 0x20, 0x8F};
25 | unsigned char buffer1[210];
26 | unsigned char buffer2[35] = {0x43, 0x54, 0x62, 0x7A, 0x18, 0xC3, 0xD6, 0xB3, 0x9A, 0x56, 0xF6, 0x1C, 0x14, 0x3F, 0x0C, 0x1D, 0x3B, 0x36, 0x83, 0xB1, 0x39, 0x51, 0x4A, 0xAA, 0x09, 0x3E, 0xFE, 0x44, 0xAF, 0xDE, 0xC3, 0x20, 0x9D, 0x42, 0x3A};
27 | unsigned char buffer3[132];
28 | unsigned char buffer4[21] = {0xED, 0x25, 0xD1, 0xBB, 0xBC, 0x27, 0x9F, 0x02, 0xA2, 0xA9, 0x11, 0x00, 0x0C, 0xB3, 0x52, 0xC0, 0xBD, 0xE3, 0x1B, 0x49, 0xC7};
29 | int i0_index[11] = {18, 22, 23, 0, 5, 19, 32, 31, 10, 21, 30};
30 | uint8_t w,x,y,z;
31 | int i, j;
32 |
33 | // Load the input into the buffer
34 | for (i = 0; i < 210; i++)
35 | {
36 | // We need to swap the byte order around so it is the right endianness
37 | uint32_t in_word = block_words[((i % 64)>>2)];
38 | uint32_t in_byte = (in_word >> ((3-(i % 4)) << 3)) & 0xff;
39 | buffer1[i] = in_byte;
40 | }
41 | // Next a scrambling
42 | for (i = 0; i < 840; i++)
43 | {
44 | // We have to do unsigned, 32-bit modulo, or we get the wrong indices
45 | x = buffer1[((i-155) & 0xffffffff) % 210];
46 | y = buffer1[((i-57) & 0xffffffff) % 210];
47 | z = buffer1[((i-13) & 0xffffffff) % 210];
48 | w = buffer1[(i & 0xffffffff) % 210];
49 | buffer1[i % 210] = (rol8(y, 5) + (rol8(z, 3) ^ w) - rol8(x,7)) & 0xff;
50 | }
51 | printf("Garbling...\n");
52 | // I have no idea what this is doing (yet), but it gives the right output
53 | garble(buffer0, buffer1, buffer2, buffer3, buffer4);
54 |
55 | // Fill the output with 0xE1
56 | for (i = 0; i < 16; i++)
57 | keyOut[i] = 0xE1;
58 |
59 | // Now we use all the buffers we have calculated to grind out the output. First buffer3
60 | for (i = 0; i < 11; i++)
61 | {
62 | // Note that this is addition (mod 255) and not XOR
63 | // Also note that we only use certain indices
64 | // And that index 3 is hard-coded to be 0x3d (Maybe we can hack this up by changing buffer3[0] to be 0xdc?
65 | if (i == 3)
66 | keyOut[i] = 0x3d;
67 | else
68 | keyOut[i] = ((keyOut[i] + buffer3[i0_index[i] * 4]) & 0xff);
69 | }
70 |
71 | // Then buffer0
72 | for (i = 0; i < 20; i++)
73 | keyOut[i % 16] ^= buffer0[i];
74 |
75 | // Then buffer2
76 | for (i = 0; i < 35; i++)
77 | keyOut[i % 16] ^= buffer2[i];
78 |
79 | // Do buffer1
80 | for (i = 0; i < 210; i++)
81 | keyOut[(i % 16)] ^= buffer1[i];
82 |
83 |
84 | // Now we do a kind of reverse-scramble
85 | for (j = 0; j < 16; j++)
86 | {
87 | for (i = 0; i < 16; i++)
88 | {
89 | x = keyOut[((i-7) & 0xffffffff) % 16];
90 | y = keyOut[i % 16];
91 | z = keyOut[((i-37) & 0xffffffff) % 16];
92 | w = keyOut[((i-177) & 0xffffffff) % 16];
93 | keyOut[i] = rol8(x, 1) ^ y ^ rol8(z, 6) ^ rol8(w, 5);
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/lib/plist.h:
--------------------------------------------------------------------------------
1 | #ifndef PLIST_H
2 | #define PLIST_H
3 |
4 | #if defined(_WIN32) && defined(_MSC_VER)
5 | typedef signed __int8 int8_t;
6 | typedef unsigned __int8 uint8_t;
7 | typedef __int16 int16_t;
8 | typedef unsigned __int16 uint16_t;
9 | typedef __int32 int32_t;
10 | typedef unsigned __int32 uint32_t;
11 | typedef __int64 int64_t;
12 | typedef unsigned __int64 uint64_t;
13 | #else
14 | #include
15 | #endif
16 |
17 | #define PLIST_TYPE_PRIMITIVE 0x00
18 | #define PLIST_TYPE_INTEGER 0x10
19 | #define PLIST_TYPE_REAL 0x20
20 | #define PLIST_TYPE_DATA 0x40
21 | #define PLIST_TYPE_STRING 0x50
22 | #define PLIST_TYPE_ARRAY 0xA0
23 | #define PLIST_TYPE_DICT 0xD0
24 |
25 | #define PLIST_PRIMITIVE_TRUE 0x08
26 | #define PLIST_PRIMITIVE_FALSE 0x09
27 |
28 | typedef struct plist_object_s plist_object_t;
29 |
30 | plist_object_t *plist_object_true();
31 | plist_object_t *plist_object_false();
32 | plist_object_t *plist_object_integer(uint64_t value);
33 | plist_object_t *plist_object_real(double value);
34 | plist_object_t *plist_object_data(const uint8_t *value, uint32_t valuelen);
35 | plist_object_t *plist_object_string(const char *value);
36 | plist_object_t *plist_object_array(uint32_t size, ...);
37 | plist_object_t *plist_object_dict(uint32_t size, ...);
38 |
39 | uint8_t plist_object_get_type(plist_object_t *object);
40 | int plist_object_primitive_get_value(plist_object_t *object, uint8_t *value);
41 | int plist_object_integer_get_value(plist_object_t *object, int64_t *value);
42 | int plist_object_real_get_value(plist_object_t *object, double *value);
43 | int plist_object_data_get_value(plist_object_t *object, const uint8_t **value, uint32_t *valuelen);
44 | int plist_object_string_get_value(plist_object_t *object, const char **value);
45 | const plist_object_t *plist_object_array_get_value(plist_object_t *object, uint32_t idx);
46 | const plist_object_t *plist_object_dict_get_value(plist_object_t *object, const char *key);
47 |
48 | plist_object_t *plist_object_from_bplist(const uint8_t *data, uint32_t datalen);
49 | int plist_object_to_bplist(plist_object_t *object, uint8_t **data, uint32_t *datalen);
50 |
51 | void plist_object_destroy(plist_object_t *object);
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/src/lib/raop_buffer.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef RAOP_BUFFER_H
16 | #define RAOP_BUFFER_H
17 |
18 | typedef struct raop_buffer_s raop_buffer_t;
19 |
20 | /* From ALACMagicCookieDescription.txt at http://http://alac.macosforge.org/ */
21 | typedef struct {
22 | unsigned int frameLength;
23 | unsigned char compatibleVersion;
24 | unsigned char bitDepth;
25 | unsigned char pb;
26 | unsigned char mb;
27 | unsigned char kb;
28 | unsigned char numChannels;
29 | unsigned short maxRun;
30 | unsigned int maxFrameBytes;
31 | unsigned int avgBitRate;
32 | unsigned int sampleRate;
33 | } ALACSpecificConfig;
34 |
35 | typedef int (*raop_resend_cb_t)(void *opaque, unsigned short seqno, unsigned short count);
36 |
37 | raop_buffer_t *raop_buffer_init(const char *rtpmap,
38 | const char *fmtp,
39 | const unsigned char *aeskey,
40 | const unsigned char *aesiv);
41 |
42 | const ALACSpecificConfig *raop_buffer_get_config(raop_buffer_t *raop_buffer);
43 | int raop_buffer_queue(raop_buffer_t *raop_buffer, unsigned char *data, unsigned short datalen, int use_seqnum);
44 | const void *raop_buffer_dequeue(raop_buffer_t *raop_buffer, int *length, int no_resend);
45 | void raop_buffer_handle_resends(raop_buffer_t *raop_buffer, raop_resend_cb_t resend_cb, void *opaque);
46 | void raop_buffer_flush(raop_buffer_t *raop_buffer, int next_seq);
47 |
48 | void raop_buffer_destroy(raop_buffer_t *raop_buffer);
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/src/lib/raop_rtp.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef RAOP_RTP_H
16 | #define RAOP_RTP_H
17 |
18 | /* For raop_callbacks_t */
19 | #include "raop.h"
20 | #include "logger.h"
21 |
22 | #define RAOP_AESKEY_LEN 16
23 | #define RAOP_AESIV_LEN 16
24 | #define RAOP_PACKET_LEN 32768
25 |
26 | typedef struct raop_rtp_s raop_rtp_t;
27 |
28 | raop_rtp_t *raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, const char *remote,
29 | const char *rtpmap, const char *fmtp,
30 | const unsigned char *aeskey, const unsigned char *aesiv);
31 | void raop_rtp_start(raop_rtp_t *raop_rtp, int use_udp, unsigned short control_rport, unsigned short timing_rport,
32 | unsigned short *control_lport, unsigned short *timing_lport, unsigned short *data_lport);
33 | void raop_rtp_set_volume(raop_rtp_t *raop_rtp, float volume);
34 | void raop_rtp_set_metadata(raop_rtp_t *raop_rtp, const char *data, int datalen);
35 | void raop_rtp_set_coverart(raop_rtp_t *raop_rtp, const char *data, int datalen);
36 | void raop_rtp_remote_control_id(raop_rtp_t *raop_rtp, const char *dacp_id, const char *active_remote_header);
37 | void raop_rtp_set_progress(raop_rtp_t *raop_rtp, unsigned int start, unsigned int curr, unsigned int end);
38 | void raop_rtp_flush(raop_rtp_t *raop_rtp, int next_seq);
39 | void raop_rtp_stop(raop_rtp_t *raop_rtp);
40 | void raop_rtp_destroy(raop_rtp_t *raop_rtp);
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/src/lib/rsakey.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef RSAKEY_H
16 | #define RSAKEY_H
17 |
18 | typedef struct rsakey_s rsakey_t;
19 |
20 | rsakey_t *rsakey_init(const unsigned char *modulus, int mod_len,
21 | const unsigned char *pub_exp, int pub_len,
22 | const unsigned char *priv_exp, int priv_len,
23 | const unsigned char *p, int p_len,
24 | const unsigned char *q, int q_len,
25 | const unsigned char *dP, int dP_len,
26 | const unsigned char *dQ, int dQ_len,
27 | const unsigned char *qInv, int qInv_len);
28 | rsakey_t *rsakey_init_pem(const char *pemstr);
29 |
30 | int rsakey_sign(rsakey_t *rsakey, char *dst, int dstlen, const char *b64digest,
31 | unsigned char *ipaddr, int ipaddrlen,
32 | unsigned char *hwaddr, int hwaddrlen);
33 |
34 | int rsakey_decrypt(rsakey_t *rsakey, unsigned char *dst, int dstlen, const char *b64input);
35 | int rsakey_decode(rsakey_t *rsakey, unsigned char *dst, int dstlen, const char *b64input);
36 |
37 | void rsakey_destroy(rsakey_t *rsakey);
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/src/lib/rsapem.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "rsapem.h"
21 | #include "base64.h"
22 |
23 | #define RSAPRIVHEADER "-----BEGIN RSA PRIVATE KEY-----"
24 | #define RSAPRIVFOOTER "-----END RSA PRIVATE KEY-----"
25 |
26 | struct rsapem_s {
27 | unsigned char *data;
28 | unsigned int datalen;
29 | unsigned int datapos;
30 | };
31 |
32 | rsapem_t *
33 | rsapem_init(const char *pemstr)
34 | {
35 | rsapem_t *rsapem=NULL;
36 | const char *header;
37 | const char *footer;
38 | base64_t *b64dec;
39 | unsigned char *data;
40 | int datalen;
41 |
42 | header = strstr(pemstr, RSAPRIVHEADER);
43 | footer = strstr(pemstr, RSAPRIVFOOTER);
44 | if (!header || !footer) {
45 | return NULL;
46 | }
47 |
48 |
49 | /* Base64 decode the whole input excluding header and footer */
50 | b64dec = base64_init(NULL, 0, 1);
51 | datalen = base64_decode(b64dec, &data, pemstr+sizeof(RSAPRIVHEADER),
52 | (footer-header)-sizeof(RSAPRIVHEADER));
53 | base64_destroy(b64dec);
54 | b64dec = NULL;
55 |
56 | if (datalen < 0) {
57 | return NULL;
58 | }
59 |
60 | #ifdef RSAPEM_DEBUG
61 | {
62 | int i;
63 | printf("Decoded output:\n");
64 | for (i=0; idata = data;
88 | rsapem->datalen = datalen;
89 | rsapem->datapos = 4;
90 |
91 | data = NULL;
92 | datalen = rsapem_read_vector(rsapem, &data);
93 | if (datalen != 1 && data[0] != 0x00) {
94 | free(data);
95 | rsapem_destroy(rsapem);
96 | return NULL;
97 | }
98 | free(data);
99 | return rsapem;
100 | }
101 |
102 | void
103 | rsapem_destroy(rsapem_t *rsapem)
104 | {
105 | if (rsapem) {
106 | free(rsapem->data);
107 | free(rsapem);
108 | }
109 | }
110 |
111 | int
112 | rsapem_read_vector(rsapem_t *rsapem, unsigned char **data)
113 | {
114 | unsigned int length;
115 | unsigned char *ptr;
116 |
117 | if (rsapem->datalen-rsapem->datapos < 2) {
118 | return -1;
119 | }
120 | if (rsapem->data[rsapem->datapos] != 0x02) {
121 | return -2;
122 | }
123 |
124 | /* Read vector length */
125 | length = rsapem->data[rsapem->datapos+1];
126 | if (length <= 0x80) {
127 | rsapem->datapos += 2;
128 | } else if (length == 0x81) {
129 | if (rsapem->datalen-rsapem->datapos < 3) {
130 | return -3;
131 | }
132 | length = rsapem->data[rsapem->datapos+2];
133 | rsapem->datapos += 3;
134 | } else if (length == 0x82) {
135 | if (rsapem->datalen-rsapem->datapos < 4) {
136 | return -3;
137 | }
138 | length = (rsapem->data[rsapem->datapos+2] << 8) |
139 | rsapem->data[rsapem->datapos+3];
140 | rsapem->datapos += 4;
141 | } else {
142 | return -3;
143 | }
144 |
145 | /* Check that we have enough data available */
146 | if (rsapem->datalen-rsapem->datapos < length) {
147 | return -4;
148 | }
149 |
150 | /* Allocate data buffer and read bytes */
151 | ptr = malloc(length);
152 | if (!ptr) {
153 | return -5;
154 | }
155 | memcpy(ptr, rsapem->data+rsapem->datapos, length);
156 | rsapem->datapos += length;
157 |
158 | /* Return buffer and length */
159 | *data = ptr;
160 | return length;
161 | }
162 |
163 |
--------------------------------------------------------------------------------
/src/lib/rsapem.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef RSAPEM_H
16 | #define RSAPEM_H
17 |
18 | typedef struct rsapem_s rsapem_t;
19 |
20 | rsapem_t *rsapem_init(const char *pemstr);
21 | int rsapem_read_vector(rsapem_t *rsapem, unsigned char **data);
22 | void rsapem_destroy(rsapem_t *rsapem);
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/src/lib/sdp.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include
16 | #include
17 | #include
18 |
19 | #include "sdp.h"
20 |
21 | struct sdp_s {
22 | char *data;
23 |
24 | /* Actual SDP records */
25 | const char *version;
26 | const char *origin;
27 | const char *connection;
28 | const char *session;
29 | const char *time;
30 | const char *media;
31 |
32 | /* Additional SDP records */
33 | const char *rtpmap;
34 | const char *fmtp;
35 | const char *rsaaeskey;
36 | const char *fpaeskey;
37 | const char *aesiv;
38 | const char *min_latency;
39 | };
40 |
41 | static void
42 | parse_sdp_line(sdp_t *sdp, char *line)
43 | {
44 | int len = strlen(line);
45 | if (len < 2 || line[1] != '=') {
46 | return;
47 | }
48 |
49 | switch (line[0]) {
50 | case 'v':
51 | sdp->version = &line[2];
52 | break;
53 | case 'o':
54 | sdp->origin = &line[2];
55 | break;
56 | case 's':
57 | sdp->session = &line[2];
58 | break;
59 | case 'c':
60 | sdp->connection = &line[2];
61 | break;
62 | case 't':
63 | sdp->time = &line[2];
64 | break;
65 | case 'm':
66 | sdp->media = &line[2];
67 | break;
68 | case 'a':
69 | {
70 | char *key;
71 | char *value;
72 |
73 | /* Parse key and value */
74 | key = &line[2];
75 | value = strstr(line, ":");
76 | if (!value) break;
77 | *(value++) = '\0';
78 |
79 | if (!strcmp(key, "rtpmap") && !sdp->rtpmap) {
80 | sdp->rtpmap = value;
81 | } else if (!strcmp(key, "fmtp") && !sdp->fmtp) {
82 | sdp->fmtp = value;
83 | } else if (!strcmp(key, "rsaaeskey")) {
84 | sdp->rsaaeskey = value;
85 | } else if (!strcmp(key, "fpaeskey")) {
86 | sdp->fpaeskey = value;
87 | } else if (!strcmp(key, "aesiv")) {
88 | sdp->aesiv = value;
89 | } else if (!strcmp(key, "min-latency")) {
90 | sdp->min_latency = value;
91 | }
92 | break;
93 | }
94 | }
95 | }
96 |
97 | static void
98 | parse_sdp_data(sdp_t *sdp)
99 | {
100 | int pos, len;
101 |
102 | pos = 0;
103 | len = strlen(sdp->data);
104 | while (pos < len) {
105 | int lfpos;
106 |
107 | /* Find newline in string */
108 | for (lfpos=pos; sdp->data[lfpos]; lfpos++) {
109 | if (sdp->data[lfpos] == '\n') {
110 | break;
111 | }
112 | }
113 | if (sdp->data[lfpos] != '\n') {
114 | break;
115 | }
116 |
117 | /* Replace newline with '\0' and parse line */
118 | sdp->data[lfpos] = '\0';
119 | if (lfpos > pos && sdp->data[lfpos-1] == '\r') {
120 | sdp->data[lfpos-1] = '\0';
121 | }
122 | parse_sdp_line(sdp, sdp->data+pos);
123 | pos = lfpos+1;
124 | }
125 | }
126 |
127 | sdp_t *
128 | sdp_init(const char *sdpdata, int sdpdatalen)
129 | {
130 | sdp_t *sdp;
131 |
132 | sdp = calloc(1, sizeof(sdp_t));
133 | if (!sdp) {
134 | return NULL;
135 | }
136 |
137 | /* Allocate data buffer */
138 | sdp->data = malloc(sdpdatalen+1);
139 | if (!sdp->data) {
140 | free(sdp);
141 | return NULL;
142 | }
143 | memcpy(sdp->data, sdpdata, sdpdatalen);
144 | sdp->data[sdpdatalen] = '\0';
145 | parse_sdp_data(sdp);
146 | return sdp;
147 | }
148 |
149 | void
150 | sdp_destroy(sdp_t *sdp)
151 | {
152 | if (sdp) {
153 | free(sdp->data);
154 | free(sdp);
155 | }
156 | }
157 |
158 | const char *
159 | sdp_get_version(sdp_t *sdp)
160 | {
161 | assert(sdp);
162 |
163 | return sdp->version;
164 | }
165 |
166 | const char *
167 | sdp_get_origin(sdp_t *sdp)
168 | {
169 | assert(sdp);
170 |
171 | return sdp->origin;
172 | }
173 |
174 | const char *
175 | sdp_get_session(sdp_t *sdp)
176 | {
177 | assert(sdp);
178 |
179 | return sdp->session;
180 | }
181 |
182 | const char *
183 | sdp_get_connection(sdp_t *sdp)
184 | {
185 | assert(sdp);
186 |
187 | return sdp->connection;
188 | }
189 |
190 | const char *
191 | sdp_get_time(sdp_t *sdp)
192 | {
193 | assert(sdp);
194 |
195 | return sdp->time;
196 | }
197 |
198 | const char *
199 | sdp_get_media(sdp_t *sdp)
200 | {
201 | assert(sdp);
202 |
203 | return sdp->media;
204 | }
205 |
206 | const char *
207 | sdp_get_rtpmap(sdp_t *sdp)
208 | {
209 | assert(sdp);
210 |
211 | return sdp->rtpmap;
212 | }
213 |
214 | const char *
215 | sdp_get_fmtp(sdp_t *sdp)
216 | {
217 | assert(sdp);
218 |
219 | return sdp->fmtp;
220 | }
221 |
222 | const char *
223 | sdp_get_rsaaeskey(sdp_t *sdp)
224 | {
225 | assert(sdp);
226 |
227 | return sdp->rsaaeskey;
228 | }
229 |
230 | const char *
231 | sdp_get_fpaeskey(sdp_t *sdp)
232 | {
233 | assert(sdp);
234 |
235 | return sdp->fpaeskey;
236 | }
237 |
238 | const char *
239 | sdp_get_aesiv(sdp_t *sdp)
240 | {
241 | assert(sdp);
242 |
243 | return sdp->aesiv;
244 | }
245 |
246 | const char *
247 | sdp_get_min_latency(sdp_t *sdp)
248 | {
249 | assert(sdp);
250 |
251 | return sdp->min_latency;
252 | }
253 |
254 |
--------------------------------------------------------------------------------
/src/lib/sdp.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef SDP_H
16 | #define SDP_H
17 |
18 | typedef struct sdp_s sdp_t;
19 |
20 | sdp_t *sdp_init(const char *sdpdata, int sdpdatalen);
21 |
22 | const char *sdp_get_version(sdp_t *sdp);
23 | const char *sdp_get_origin(sdp_t *sdp);
24 | const char *sdp_get_session(sdp_t *sdp);
25 | const char *sdp_get_connection(sdp_t *sdp);
26 | const char *sdp_get_time(sdp_t *sdp);
27 | const char *sdp_get_media(sdp_t *sdp);
28 | const char *sdp_get_rtpmap(sdp_t *sdp);
29 | const char *sdp_get_fmtp(sdp_t *sdp);
30 | const char *sdp_get_rsaaeskey(sdp_t *sdp);
31 | const char *sdp_get_fpaeskey(sdp_t *sdp);
32 | const char *sdp_get_aesiv(sdp_t *sdp);
33 | const char *sdp_get_min_latency(sdp_t *sdp);
34 |
35 | void sdp_destroy(sdp_t *sdp);
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/src/lib/sockets.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef SOCKETS_H
16 | #define SOCKETS_H
17 |
18 | #if defined(WIN32)
19 | typedef int socklen_t;
20 |
21 | #ifndef SHUT_RD
22 | # define SHUT_RD SD_RECEIVE
23 | #endif
24 | #ifndef SHUT_WR
25 | # define SHUT_WR SD_SEND
26 | #endif
27 | #ifndef SHUT_RDWR
28 | # define SHUT_RDWR SD_BOTH
29 | #endif
30 |
31 | #define SOCKET_GET_ERROR() WSAGetLastError()
32 | #define SOCKET_SET_ERROR(value) WSASetLastError(value)
33 | #define SOCKET_ERRORNAME(name) WSA##name
34 |
35 | #define WSAEAGAIN WSAEWOULDBLOCK
36 | #define WSAENOMEM WSA_NOT_ENOUGH_MEMORY
37 |
38 | #else
39 |
40 | #define closesocket close
41 | #define ioctlsocket ioctl
42 |
43 | #define SOCKET_GET_ERROR() (errno)
44 | #define SOCKET_SET_ERROR(value) (errno = (value))
45 | #define SOCKET_ERRORNAME(name) name
46 |
47 | #endif
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/src/lib/threads.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef THREADS_H
16 | #define THREADS_H
17 |
18 | #if defined(WIN32)
19 | #include
20 |
21 | #define sleepms(x) Sleep(x)
22 |
23 | typedef HANDLE thread_handle_t;
24 |
25 | #define THREAD_RETVAL DWORD WINAPI
26 | #define THREAD_CREATE(handle, func, arg) \
27 | handle = CreateThread(NULL, 0, func, arg, 0, NULL)
28 | #define THREAD_JOIN(handle) do { WaitForSingleObject(handle, INFINITE); CloseHandle(handle); } while(0)
29 |
30 | typedef HANDLE mutex_handle_t;
31 |
32 | #define MUTEX_CREATE(handle) handle = CreateMutex(NULL, FALSE, NULL)
33 | #define MUTEX_LOCK(handle) WaitForSingleObject(handle, INFINITE)
34 | #define MUTEX_UNLOCK(handle) ReleaseMutex(handle)
35 | #define MUTEX_DESTROY(handle) CloseHandle(handle)
36 |
37 | #else /* Use pthread library */
38 |
39 | #include
40 | #include
41 |
42 | #define sleepms(x) usleep((x)*1000)
43 |
44 | typedef pthread_t thread_handle_t;
45 |
46 | #define THREAD_RETVAL void *
47 | #define THREAD_CREATE(handle, func, arg) \
48 | if (pthread_create(&(handle), NULL, func, arg)) handle = 0
49 | #define THREAD_JOIN(handle) pthread_join(handle, NULL)
50 |
51 | typedef pthread_mutex_t mutex_handle_t;
52 |
53 | #define MUTEX_CREATE(handle) pthread_mutex_init(&(handle), NULL)
54 | #define MUTEX_LOCK(handle) pthread_mutex_lock(&(handle))
55 | #define MUTEX_UNLOCK(handle) pthread_mutex_unlock(&(handle))
56 | #define MUTEX_DESTROY(handle) pthread_mutex_destroy(&(handle))
57 |
58 | #endif
59 |
60 | #endif /* THREADS_H */
61 |
--------------------------------------------------------------------------------
/src/lib/utils.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #include
16 | #include
17 | #include
18 |
19 | char *
20 | utils_strsep(char **stringp, const char *delim)
21 | {
22 | char *original;
23 | char *strptr;
24 |
25 | if (*stringp == NULL) {
26 | return NULL;
27 | }
28 |
29 | original = *stringp;
30 | strptr = strstr(*stringp, delim);
31 | if (strptr == NULL) {
32 | *stringp = NULL;
33 | return original;
34 | }
35 | *strptr = '\0';
36 | *stringp = strptr+strlen(delim);
37 | return original;
38 | }
39 |
40 | int
41 | utils_read_file(char **dst, const char *filename)
42 | {
43 | FILE *stream;
44 | int filesize;
45 | char *buffer;
46 | int read_bytes;
47 |
48 | /* Open stream for reading */
49 | stream = fopen(filename, "rb");
50 | if (!stream) {
51 | return -1;
52 | }
53 |
54 | /* Find out file size */
55 | fseek(stream, 0, SEEK_END);
56 | filesize = ftell(stream);
57 | fseek(stream, 0, SEEK_SET);
58 |
59 | /* Allocate one extra byte for zero */
60 | buffer = malloc(filesize+1);
61 | if (!buffer) {
62 | fclose(stream);
63 | return -2;
64 | }
65 |
66 | /* Read data in a loop to buffer */
67 | read_bytes = 0;
68 | do {
69 | int ret = fread(buffer+read_bytes, 1,
70 | filesize-read_bytes, stream);
71 | if (ret == 0) {
72 | break;
73 | }
74 | read_bytes += ret;
75 | } while (read_bytes < filesize);
76 |
77 | /* Add final null byte and close stream */
78 | buffer[read_bytes] = '\0';
79 | fclose(stream);
80 |
81 | /* If read didn't finish, return error */
82 | if (read_bytes != filesize) {
83 | free(buffer);
84 | return -3;
85 | }
86 |
87 | /* Return buffer */
88 | *dst = buffer;
89 | return filesize;
90 | }
91 |
92 | int
93 | utils_hwaddr_raop(char *str, int strlen, const char *hwaddr, int hwaddrlen)
94 | {
95 | int i,j;
96 |
97 | /* Check that our string is long enough */
98 | if (strlen == 0 || strlen < 2*hwaddrlen+1)
99 | return -1;
100 |
101 | /* Convert hardware address to hex string */
102 | for (i=0,j=0; i>4) & 0x0f;
104 | int lo = hwaddr[i] & 0x0f;
105 |
106 | if (hi < 10) str[j++] = '0' + hi;
107 | else str[j++] = 'A' + hi-10;
108 | if (lo < 10) str[j++] = '0' + lo;
109 | else str[j++] = 'A' + lo-10;
110 | }
111 |
112 | /* Add string terminator */
113 | str[j++] = '\0';
114 | return j;
115 | }
116 |
117 | int
118 | utils_hwaddr_airplay(char *str, int strlen, const char *hwaddr, int hwaddrlen)
119 | {
120 | int i,j;
121 |
122 | /* Check that our string is long enough */
123 | if (strlen == 0 || strlen < 2*hwaddrlen+hwaddrlen)
124 | return -1;
125 |
126 | /* Convert hardware address to hex string */
127 | for (i=0,j=0; i>4) & 0x0f;
129 | int lo = hwaddr[i] & 0x0f;
130 |
131 | if (hi < 10) str[j++] = '0' + hi;
132 | else str[j++] = 'a' + hi-10;
133 | if (lo < 10) str[j++] = '0' + lo;
134 | else str[j++] = 'a' + lo-10;
135 |
136 | str[j++] = ':';
137 | }
138 |
139 | /* Add string terminator */
140 | if (j != 0) j--;
141 | str[j++] = '\0';
142 | return j;
143 | }
144 |
145 |
--------------------------------------------------------------------------------
/src/lib/utils.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | */
14 |
15 | #ifndef UTILS_H
16 | #define UTILS_H
17 |
18 | char *utils_strsep(char **stringp, const char *delim);
19 | int utils_read_file(char **dst, const char *pemstr);
20 | int utils_hwaddr_raop(char *str, int strlen, const char *hwaddr, int hwaddrlen);
21 | int utils_hwaddr_airplay(char *str, int strlen, const char *hwaddr, int hwaddrlen);
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/src/test/dnssd_test.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "dnssd.h"
6 | #include "compat.h"
7 |
8 | int
9 | main(int argc, char *argv[])
10 | {
11 | const char hwaddr[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB };
12 | dnssd_t *dnssd;
13 |
14 |
15 | #ifdef WIN32
16 | WORD wVersionRequested;
17 | WSADATA wsaData;
18 |
19 | wVersionRequested = MAKEWORD(2, 2);
20 | if (WSAStartup(wVersionRequested, &wsaData) != 0) {
21 | return -1;
22 | }
23 | if (LOBYTE(wsaData.wVersion) != 2 ||
24 | HIBYTE(wsaData.wVersion) != 2) {
25 | return -1;
26 | }
27 | #endif
28 |
29 | dnssd = dnssd_init(NULL);
30 | if (!dnssd) {
31 | printf("Failed to init dnssd\n");
32 | return -1;
33 | }
34 | dnssd_register_raop(dnssd, "Test", 5000, hwaddr, sizeof(hwaddr));
35 | dnssd_register_airplay(dnssd, "Test", 6000, hwaddr, sizeof(hwaddr));
36 |
37 | sleepms(60000);
38 |
39 | dnssd_unregister_raop(dnssd);
40 | dnssd_unregister_airplay(dnssd);
41 | dnssd_destroy(dnssd);
42 |
43 | #ifdef WIN32
44 | WSACleanup();
45 | #endif
46 |
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/dnssd_test.m:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "dnssd.h"
7 | #include "compat.h"
8 |
9 | int
10 | main(int argc, char *argv[])
11 | {
12 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
13 | const char hwaddr[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB };
14 | dnssd_t *dnssd;
15 |
16 | dnssd = dnssd_init(NULL);
17 | if (!dnssd) {
18 | printf("Failed to init dnssd\n");
19 | return -1;
20 | }
21 | dnssd_register_raop(dnssd, "Test", 5000, hwaddr, sizeof(hwaddr));
22 | dnssd_register_airplay(dnssd, "Test", 6000, hwaddr, sizeof(hwaddr));
23 |
24 | sleepms(60000);
25 |
26 | dnssd_unregister_raop(dnssd);
27 | dnssd_unregister_airplay(dnssd);
28 | dnssd_destroy(dnssd);
29 | [pool release];
30 |
31 | return 0;
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/example.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Starts the AirPlay server (name "FakePort") and dumps the received contents
3 | * to files:
4 | * - audio.pcm : decoded audio content
5 | * - metadata.bin : meta data
6 | * - covertart.jpg : cover art
7 | *
8 | * Requires avahi-daemon to run. Also requires file "airplay.key" in the same directory.
9 | *
10 | * Compile with: gcc -o example -g -I../../include/shairplay example.c -lshairplay
11 | */
12 |
13 | #include
14 | #include
15 | #include
16 |
17 | #ifdef WIN32
18 | #include
19 | #endif
20 |
21 | #include "dnssd.h"
22 | #include "raop.h"
23 |
24 | static int running;
25 |
26 | #ifndef WIN32
27 |
28 | #include
29 | static void
30 | signal_handler(int sig)
31 | {
32 | switch (sig) {
33 | case SIGINT:
34 | case SIGTERM:
35 | running = 0;
36 | break;
37 | }
38 | }
39 | static void
40 | init_signals(void)
41 | {
42 | struct sigaction sigact;
43 |
44 | sigact.sa_handler = signal_handler;
45 | sigemptyset(&sigact.sa_mask);
46 | sigact.sa_flags = 0;
47 | sigaction(SIGINT, &sigact, NULL);
48 | sigaction(SIGTERM, &sigact, NULL);
49 | }
50 |
51 | #endif
52 |
53 | static void *
54 | audio_init(void *cls, int bits, int channels, int samplerate)
55 | {
56 | return fopen("audio.pcm", "wb");
57 | }
58 |
59 | static void
60 | audio_set_volume(void *cls, void *session, float volume)
61 | {
62 | printf("Setting volume to %f\n", volume);
63 | }
64 |
65 | static void
66 | audio_set_metadata(void *cls, void *session, const void *buffer, int buflen)
67 | {
68 | int orig = buflen;
69 | FILE *file = fopen("metadata.bin", "wb");
70 | while (buflen > 0) {
71 | buflen -= fwrite(buffer+orig-buflen, 1, buflen, file);
72 | }
73 | fclose(file);
74 | printf("Metadata of length %d saved as metadata.bin\n", orig);
75 | }
76 |
77 | static void
78 | audio_set_coverart(void *cls, void *session, const void *buffer, int buflen)
79 | {
80 | int orig = buflen;
81 | FILE *file = fopen("coverart.jpg", "wb");
82 | while (buflen > 0) {
83 | buflen -= fwrite(buffer+orig-buflen, 1, buflen, file);
84 | }
85 | fclose(file);
86 | printf("Coverart of length %d saved as coverart.jpg\n", orig);
87 | }
88 |
89 | static void
90 | audio_process(void *cls, void *session, const void *buffer, int buflen)
91 | {
92 | int orig = buflen;
93 | while (buflen > 0) {
94 | buflen -= fwrite(buffer+orig-buflen, 1, buflen, session);
95 | }
96 | }
97 |
98 | static void
99 | audio_flush(void *cls, void *session)
100 | {
101 | printf("Flushing audio\n");
102 | }
103 |
104 | static void
105 | audio_destroy(void *cls, void *session)
106 | {
107 | fclose(session);
108 | }
109 |
110 | static void
111 | raop_log_callback(void *cls, int level, const char *msg)
112 | {
113 | printf("RAOP LOG(%d): %s\n", level, msg);
114 | }
115 |
116 | int
117 | main(int argc, char *argv[])
118 | {
119 | const char *name = "FakePort";
120 | unsigned short raop_port = 5000;
121 | const char hwaddr[] = { 0x48, 0x5d, 0x60, 0x7c, 0xee, 0x22 };
122 |
123 | dnssd_t *dnssd;
124 | raop_t *raop;
125 | raop_callbacks_t raop_cbs;
126 |
127 | int error;
128 |
129 | raop_cbs.cls = NULL;
130 | raop_cbs.audio_init = audio_init;
131 | raop_cbs.audio_set_volume = audio_set_volume;
132 | raop_cbs.audio_set_metadata = audio_set_metadata;
133 | raop_cbs.audio_set_coverart = audio_set_coverart;
134 | raop_cbs.audio_process = audio_process;
135 | raop_cbs.audio_flush = audio_flush;
136 | raop_cbs.audio_destroy = audio_destroy;
137 |
138 | raop = raop_init_from_keyfile(10, &raop_cbs, "airport.key", NULL);
139 | if (raop == NULL) {
140 | fprintf(stderr, "Could not initialize the RAOP service (airport.key missing?)\n");
141 | return -1;
142 | }
143 |
144 | raop_set_log_level(raop, RAOP_LOG_DEBUG);
145 | raop_set_log_callback(raop, &raop_log_callback, NULL);
146 | raop_start(raop, &raop_port, hwaddr, sizeof(hwaddr), NULL);
147 |
148 | error = 0;
149 | dnssd = dnssd_init(&error);
150 | if (error) {
151 | fprintf(stderr, "ERROR: Could not initialize dnssd library!\n");
152 | fprintf(stderr, "------------------------------------------\n");
153 | fprintf(stderr, "You could try the following resolutions based on your OS:\n");
154 | fprintf(stderr, "Windows: Try installing http://support.apple.com/kb/DL999\n");
155 | fprintf(stderr, "Debian/Ubuntu: Try installing libavahi-compat-libdnssd-dev package\n");
156 | raop_destroy(raop);
157 | return -1;
158 | }
159 |
160 | dnssd_register_raop(dnssd, name, raop_port, hwaddr, sizeof(hwaddr), 1);
161 |
162 | printf("Startup complete... Kill with Ctrl+C\n");
163 |
164 | running = 1;
165 | while (running != 0) {
166 | #ifndef WIN32
167 | sleep(1);
168 | #else
169 | Sleep(1000);
170 | #endif
171 | }
172 |
173 | dnssd_unregister_raop(dnssd);
174 | dnssd_destroy(dnssd);
175 |
176 | raop_stop(raop);
177 | raop_destroy(raop);
178 |
179 | return 0;
180 | }
181 |
182 |
--------------------------------------------------------------------------------
/src/test/test.py:
--------------------------------------------------------------------------------
1 | import time
2 | from struct import *
3 | from Shairplay import *
4 |
5 | hwaddr = pack('BBBBBB', 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB)
6 | class SampleCallbacks(RaopCallbacks):
7 | def audio_init(self, bits, channels, samplerate):
8 | print "Initializing", bits, channels, samplerate
9 | def audio_process(self, session, buffer):
10 | print "Processing", + len(buffer), "bytes of audio"
11 | def audio_destroy(self, session):
12 | print "Destroying"
13 | def audio_set_volume(self, session, volume):
14 | print "Set volume to", volume
15 | def audio_set_metadata(self, session, metadata):
16 | print "Got", len(metadata), "bytes of metadata"
17 | def audio_set_coverart(self, session, coverart):
18 | print "Got", len(coverart), "bytes of coverart"
19 |
20 | shairplay = LoadShairplay(".")
21 | callbacks = SampleCallbacks()
22 |
23 | def log_callback(level, message):
24 | print "Level", level, ":", message
25 |
26 | raop = RaopService(shairplay, 10, callbacks)
27 | raop.set_log_level(RaopLogLevel.DEBUG)
28 | raop.set_log_callback(log_callback)
29 | port = raop.start(5000, hwaddr)
30 |
31 | dnssd = DnssdService(shairplay)
32 | dnssd.register_raop("RAOP test", port, hwaddr)
33 |
34 | time.sleep(50)
35 |
36 | dnssd.unregister_raop()
37 | raop.stop()
38 |
39 | del dnssd
40 | del raop
41 |
42 |
--------------------------------------------------------------------------------