Fix typo in 9b54bd30006c008b4a951331b273613d5bac3abf
[pm.git] / ipc / nfc / Nfc.cpp
blob3d3f3e4f1c53d3d8ad6f67c39442b5432b90194f
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set sw=2 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"
11 #include <fcntl.h>
12 #include <sys/socket.h>
13 #include <sys/un.h>
15 #undef CHROMIUM_LOG
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)
19 #else
20 #define CHROMIUM_LOG(args...)
21 #endif
23 #include "jsfriendapi.h"
24 #include "mozilla/ArrayUtils.h"
25 #include "mozilla/ipc/UnixSocketConnector.h"
26 #include "nsThreadUtils.h" // For NS_IsMainThread.
28 using namespace mozilla::ipc;
30 namespace {
32 static const char NFC_SOCKET_NAME[] = "/dev/socket/nfcd";
34 // Network port to connect to for adb forwarded sockets when doing
35 // desktop development.
36 static const uint32_t NFC_TEST_PORT = 6400;
38 class SendNfcSocketDataTask final : public nsRunnable
40 public:
41 SendNfcSocketDataTask(NfcConsumer* aConsumer, UnixSocketRawData* aRawData)
42 : mConsumer(aConsumer)
43 , mRawData(aRawData)
44 { }
46 NS_IMETHOD Run()
48 MOZ_ASSERT(NS_IsMainThread());
50 if (!mConsumer ||
51 mConsumer->GetConnectionStatus() != SOCKET_CONNECTED) {
52 // Probably shuting down.
53 return NS_OK;
56 mConsumer->SendSocketData(mRawData.forget());
57 return NS_OK;
60 private:
61 NfcConsumer* mConsumer;
62 nsAutoPtr<UnixSocketRawData> mRawData;
65 class NfcConnector final : public mozilla::ipc::UnixSocketConnector
67 public:
68 NfcConnector()
69 { }
71 int Create() override;
72 bool CreateAddr(bool aIsServer,
73 socklen_t& aAddrSize,
74 sockaddr_any& aAddr,
75 const char* aAddress) override;
76 bool SetUp(int aFd) override;
77 bool SetUpListenSocket(int aFd) override;
78 void GetSocketAddr(const sockaddr_any& aAddr,
79 nsAString& aAddrStr) override;
82 int
83 NfcConnector::Create()
85 MOZ_ASSERT(!NS_IsMainThread());
87 int fd = -1;
89 #if defined(MOZ_WIDGET_GONK)
90 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
91 #else
92 // If we can't hit a local loopback, fail later in connect.
93 fd = socket(AF_INET, SOCK_STREAM, 0);
94 #endif
96 if (fd < 0) {
97 NS_WARNING("Could not open nfc socket!");
98 return -1;
101 if (!SetUp(fd)) {
102 NS_WARNING("Could not set up socket!");
104 return fd;
107 bool
108 NfcConnector::CreateAddr(bool aIsServer,
109 socklen_t& aAddrSize,
110 sockaddr_any& aAddr,
111 const char* aAddress)
113 // We never open nfc socket as server.
114 MOZ_ASSERT(!aIsServer);
115 uint32_t af;
116 #if defined(MOZ_WIDGET_GONK)
117 af = AF_LOCAL;
118 #else
119 af = AF_INET;
120 #endif
121 switch (af) {
122 case AF_LOCAL:
123 aAddr.un.sun_family = af;
124 if(strlen(aAddress) > sizeof(aAddr.un.sun_path)) {
125 NS_WARNING("Address too long for socket struct!");
126 return false;
128 strcpy((char*)&aAddr.un.sun_path, aAddress);
129 aAddrSize = strlen(aAddress) + offsetof(struct sockaddr_un, sun_path) + 1;
130 break;
131 case AF_INET:
132 aAddr.in.sin_family = af;
133 aAddr.in.sin_port = htons(NFC_TEST_PORT);
134 aAddr.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
135 aAddrSize = sizeof(sockaddr_in);
136 break;
137 default:
138 NS_WARNING("Socket type not handled by connector!");
139 return false;
141 return true;
144 bool
145 NfcConnector::SetUp(int aFd)
147 // Nothing to do here.
148 return true;
151 bool
152 NfcConnector::SetUpListenSocket(int aFd)
154 // Nothing to do here.
155 return true;
158 void
159 NfcConnector::GetSocketAddr(const sockaddr_any& aAddr,
160 nsAString& aAddrStr)
162 MOZ_CRASH("This should never be called!");
165 } // anonymous namespace
167 namespace mozilla {
168 namespace ipc {
170 NfcConsumer::NfcConsumer(NfcSocketListener* aListener)
171 : mListener(aListener)
172 , mShutdown(false)
174 mAddress = NFC_SOCKET_NAME;
176 Connect(new NfcConnector(), mAddress.get());
179 void
180 NfcConsumer::Shutdown()
182 MOZ_ASSERT(NS_IsMainThread());
184 mShutdown = true;
185 Close();
188 bool
189 NfcConsumer::PostToNfcDaemon(const uint8_t* aData, size_t aSize)
191 MOZ_ASSERT(!NS_IsMainThread());
193 UnixSocketRawData* raw = new UnixSocketRawData(aData, aSize);
194 nsRefPtr<SendNfcSocketDataTask> task = new SendNfcSocketDataTask(this, raw);
195 NS_DispatchToMainThread(task);
196 return true;
199 void
200 NfcConsumer::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aData)
202 MOZ_ASSERT(NS_IsMainThread());
204 if (mListener) {
205 mListener->ReceiveSocketData(aData);
209 void
210 NfcConsumer::OnConnectSuccess()
212 // Nothing to do here.
213 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__);
216 void
217 NfcConsumer::OnConnectError()
219 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__);
220 Close();
223 void
224 NfcConsumer::OnDisconnect()
226 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__);
227 if (!mShutdown) {
228 Connect(new NfcConnector(), mAddress.get(), GetSuggestedConnectDelayMs());
232 ConnectionOrientedSocketIO*
233 NfcConsumer::GetIO()
235 return PrepareAccept(new NfcConnector());
238 } // namespace ipc
239 } // namespace mozilla