1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set sw=4 ts=8 et ft=cpp: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Copyright © 2013, Deutsche Telekom, Inc. */
9 #include "mozilla/ipc/Nfc.h"
12 #include <sys/socket.h>
16 #if (defined(MOZ_WIDGET_GONK) && defined(DEBUG))
17 #include <android/log.h>
18 #define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
20 #define CHROMIUM_LOG(args...)
23 #include "jsfriendapi.h"
24 #include "mozilla/ArrayUtils.h"
25 #include "nsThreadUtils.h" // For NS_IsMainThread.
27 using namespace mozilla::ipc
;
31 const char* NFC_SOCKET_NAME
= "/dev/socket/nfcd";
33 // Network port to connect to for adb forwarded sockets when doing
34 // desktop development.
35 const uint32_t NFC_TEST_PORT
= 6400;
37 class SendNfcSocketDataTask
: public nsRunnable
40 SendNfcSocketDataTask(NfcConsumer
* aConsumer
, UnixSocketRawData
* aRawData
)
41 : mConsumer(aConsumer
), mRawData(aRawData
)
46 MOZ_ASSERT(NS_IsMainThread());
49 mConsumer
->GetConnectionStatus() != SOCKET_CONNECTED
) {
50 // Probably shuting down.
55 mConsumer
->SendSocketData(mRawData
);
60 NfcConsumer
* mConsumer
;
61 UnixSocketRawData
* mRawData
;
64 class NfcConnector
: public mozilla::ipc::UnixSocketConnector
70 virtual ~NfcConnector()
74 virtual bool CreateAddr(bool aIsServer
,
77 const char* aAddress
);
78 virtual bool SetUp(int aFd
);
79 virtual bool SetUpListenSocket(int aFd
);
80 virtual void GetSocketAddr(const sockaddr_any
& aAddr
,
85 NfcConnector::Create()
87 MOZ_ASSERT(!NS_IsMainThread());
91 #if defined(MOZ_WIDGET_GONK)
92 fd
= socket(AF_LOCAL
, SOCK_STREAM
, 0);
94 // If we can't hit a local loopback, fail later in connect.
95 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
99 NS_WARNING("Could not open nfc socket!");
104 NS_WARNING("Could not set up socket!");
110 NfcConnector::CreateAddr(bool aIsServer
,
111 socklen_t
& aAddrSize
,
113 const char* aAddress
)
115 // We never open nfc socket as server.
116 MOZ_ASSERT(!aIsServer
);
118 #if defined(MOZ_WIDGET_GONK)
125 aAddr
.un
.sun_family
= af
;
126 if(strlen(aAddress
) > sizeof(aAddr
.un
.sun_path
)) {
127 NS_WARNING("Address too long for socket struct!");
130 strcpy((char*)&aAddr
.un
.sun_path
, aAddress
);
131 aAddrSize
= strlen(aAddress
) + offsetof(struct sockaddr_un
, sun_path
) + 1;
134 aAddr
.in
.sin_family
= af
;
135 aAddr
.in
.sin_port
= htons(NFC_TEST_PORT
);
136 aAddr
.in
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
137 aAddrSize
= sizeof(sockaddr_in
);
140 NS_WARNING("Socket type not handled by connector!");
147 NfcConnector::SetUp(int aFd
)
149 // Nothing to do here.
154 NfcConnector::SetUpListenSocket(int aFd
)
156 // Nothing to do here.
161 NfcConnector::GetSocketAddr(const sockaddr_any
& aAddr
,
164 MOZ_CRASH("This should never be called!");
167 } // anonymous namespace
172 NfcConsumer::NfcConsumer(NfcSocketListener
* aListener
)
173 : mListener(aListener
)
176 mAddress
= NFC_SOCKET_NAME
;
178 ConnectSocket(new NfcConnector(), mAddress
.get());
182 NfcConsumer::Shutdown()
184 MOZ_ASSERT(NS_IsMainThread());
191 NfcConsumer::PostToNfcDaemon(const uint8_t* aData
, size_t aSize
)
193 MOZ_ASSERT(!NS_IsMainThread());
195 UnixSocketRawData
* raw
= new UnixSocketRawData(aData
, aSize
);
196 nsRefPtr
<SendNfcSocketDataTask
> task
= new SendNfcSocketDataTask(this, raw
);
197 NS_DispatchToMainThread(task
);
202 NfcConsumer::ReceiveSocketData(nsAutoPtr
<UnixSocketRawData
>& aData
)
204 MOZ_ASSERT(NS_IsMainThread());
207 mListener
->ReceiveSocketData(aData
);
212 NfcConsumer::OnConnectSuccess()
214 // Nothing to do here.
215 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__
);
219 NfcConsumer::OnConnectError()
221 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__
);
226 NfcConsumer::OnDisconnect()
228 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__
);
230 ConnectSocket(new NfcConnector(), mAddress
.get(),
231 GetSuggestedConnectDelayMs());
236 } // namespace mozilla