Bumping manifests a=b2g-bump
[gecko.git] / ipc / nfc / Nfc.cpp
blob04f6fca4298c6336114bc6b28e0d259df53de772
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"
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 "nsThreadUtils.h" // For NS_IsMainThread.
27 using namespace mozilla::ipc;
29 namespace {
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
39 public:
40 SendNfcSocketDataTask(NfcConsumer* aConsumer, UnixSocketRawData* aRawData)
41 : mConsumer(aConsumer), mRawData(aRawData)
42 { }
44 NS_IMETHOD Run()
46 MOZ_ASSERT(NS_IsMainThread());
48 if (!mConsumer ||
49 mConsumer->GetConnectionStatus() != SOCKET_CONNECTED) {
50 // Probably shuting down.
51 delete mRawData;
52 return NS_OK;
55 mConsumer->SendSocketData(mRawData);
56 return NS_OK;
59 private:
60 NfcConsumer* mConsumer;
61 UnixSocketRawData* mRawData;
64 class NfcConnector : public mozilla::ipc::UnixSocketConnector
66 public:
67 NfcConnector()
70 virtual ~NfcConnector()
73 virtual int Create();
74 virtual bool CreateAddr(bool aIsServer,
75 socklen_t& aAddrSize,
76 sockaddr_any& aAddr,
77 const char* aAddress);
78 virtual bool SetUp(int aFd);
79 virtual bool SetUpListenSocket(int aFd);
80 virtual void GetSocketAddr(const sockaddr_any& aAddr,
81 nsAString& aAddrStr);
84 int
85 NfcConnector::Create()
87 MOZ_ASSERT(!NS_IsMainThread());
89 int fd = -1;
91 #if defined(MOZ_WIDGET_GONK)
92 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
93 #else
94 // If we can't hit a local loopback, fail later in connect.
95 fd = socket(AF_INET, SOCK_STREAM, 0);
96 #endif
98 if (fd < 0) {
99 NS_WARNING("Could not open nfc socket!");
100 return -1;
103 if (!SetUp(fd)) {
104 NS_WARNING("Could not set up socket!");
106 return fd;
109 bool
110 NfcConnector::CreateAddr(bool aIsServer,
111 socklen_t& aAddrSize,
112 sockaddr_any& aAddr,
113 const char* aAddress)
115 // We never open nfc socket as server.
116 MOZ_ASSERT(!aIsServer);
117 uint32_t af;
118 #if defined(MOZ_WIDGET_GONK)
119 af = AF_LOCAL;
120 #else
121 af = AF_INET;
122 #endif
123 switch (af) {
124 case AF_LOCAL:
125 aAddr.un.sun_family = af;
126 if(strlen(aAddress) > sizeof(aAddr.un.sun_path)) {
127 NS_WARNING("Address too long for socket struct!");
128 return false;
130 strcpy((char*)&aAddr.un.sun_path, aAddress);
131 aAddrSize = strlen(aAddress) + offsetof(struct sockaddr_un, sun_path) + 1;
132 break;
133 case AF_INET:
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);
138 break;
139 default:
140 NS_WARNING("Socket type not handled by connector!");
141 return false;
143 return true;
146 bool
147 NfcConnector::SetUp(int aFd)
149 // Nothing to do here.
150 return true;
153 bool
154 NfcConnector::SetUpListenSocket(int aFd)
156 // Nothing to do here.
157 return true;
160 void
161 NfcConnector::GetSocketAddr(const sockaddr_any& aAddr,
162 nsAString& aAddrStr)
164 MOZ_CRASH("This should never be called!");
167 } // anonymous namespace
169 namespace mozilla {
170 namespace ipc {
172 NfcConsumer::NfcConsumer(NfcSocketListener* aListener)
173 : mListener(aListener)
174 , mShutdown(false)
176 mAddress = NFC_SOCKET_NAME;
178 ConnectSocket(new NfcConnector(), mAddress.get());
181 void
182 NfcConsumer::Shutdown()
184 MOZ_ASSERT(NS_IsMainThread());
186 mShutdown = true;
187 CloseSocket();
190 bool
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);
198 return true;
201 void
202 NfcConsumer::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aData)
204 MOZ_ASSERT(NS_IsMainThread());
206 if (mListener) {
207 mListener->ReceiveSocketData(aData);
211 void
212 NfcConsumer::OnConnectSuccess()
214 // Nothing to do here.
215 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__);
218 void
219 NfcConsumer::OnConnectError()
221 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__);
222 CloseSocket();
225 void
226 NfcConsumer::OnDisconnect()
228 CHROMIUM_LOG("NFC: %s\n", __FUNCTION__);
229 if (!mShutdown) {
230 ConnectSocket(new NfcConnector(), mAddress.get(),
231 GetSuggestedConnectDelayMs());
235 } // namespace ipc
236 } // namespace mozilla