1 /*
2 * Copyright 2007-2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * Copyright 2021, Haiku, Inc.
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 * Tri-Edge AI <triedgeai@gmail.com>
8 */
9
10
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <malloc.h>
14
15 #include <String.h>
16 #include <Message.h>
17 #include <Application.h>
18
19 #include <Button.h>
20 #include <GroupLayoutBuilder.h>
21 #include <InterfaceDefs.h>
22 #include <SpaceLayoutItem.h>
23 #include <StringView.h>
24 #include <TextControl.h>
25
26 #include <bluetooth/RemoteDevice.h>
27 #include <bluetooth/LocalDevice.h>
28 #include <bluetooth/bdaddrUtils.h>
29 #include <bluetooth/bluetooth_error.h>
30
31 #include <bluetooth/HCI/btHCI_command.h>
32 #include <bluetooth/HCI/btHCI_event.h>
33
34 #include <PincodeWindow.h>
35 #include <bluetoothserver_p.h>
36 #include <CommandManager.h>
37
38
39 #define H_SEPARATION 15
40 #define V_SEPARATION 10
41 #define BD_ADDR_LABEL "BD_ADDR: "
42
43
44 static const uint32 skMessageAcceptButton = 'acCp';
45 static const uint32 skMessageCancelButton = 'mVch';
46
47
48 namespace Bluetooth
49 {
50
PincodeWindow(bdaddr_t address,hci_id hid)51 PincodeWindow::PincodeWindow(bdaddr_t address, hci_id hid)
52 : BWindow(BRect(700, 200, 1000, 400), "PIN Code Request",
53 B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
54 B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
55 fBdaddr(address),
56 fHid(hid)
57 {
58 InitUI();
59
60 // TODO: Get more info about device" ote name/features/encry/auth... etc
61 SetBDaddr(bdaddrUtils::ToString(fBdaddr));
62
63 }
64
65
PincodeWindow(RemoteDevice * rDevice)66 PincodeWindow::PincodeWindow(RemoteDevice* rDevice)
67 : BWindow(BRect(700, 200, 1000, 400), "PIN Code Request",
68 B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
69 B_NOT_ZOOMABLE | B_NOT_RESIZABLE)
70 {
71 InitUI();
72
73 // TODO: Get more info about device" ote name/features/encry/auth... etc
74 SetBDaddr(bdaddrUtils::ToString(rDevice->GetBluetoothAddress()));
75 fHid = (rDevice->GetLocalDeviceOwner())->ID();
76 }
77
78
79 void
InitUI()80 PincodeWindow::InitUI()
81 {
82 SetLayout(new BGroupLayout(B_HORIZONTAL));
83
84 fIcon = new BluetoothIconView();
85
86 fMessage = new BStringView("fMessage", "Input the PIN code to pair with");
87 fMessage2 = new BStringView("fMessage2", "the following Bluetooth device.");
88
89 fDeviceLabel = new BStringView("fDeviceLabel","Device Name: ");
90 fDeviceLabel->SetFont(be_bold_font);
91
92 fDeviceText = new BStringView("fDeviceText", "<unknown_device>");
93
94 fAddressLabel = new BStringView("fAddressLabel", "MAC Address: ");
95 fAddressLabel->SetFont(be_bold_font);
96
97 fAddressText = new BStringView("fAddressText", "<mac_address>");
98
99 fPincodeText = new BTextControl("fPINCode", "PIN Code:", "0000", NULL);
100 fPincodeText->TextView()->SetMaxBytes(16 * sizeof(fPincodeText->Text()[0]));
101 fPincodeText->MakeFocus();
102
103 fAcceptButton = new BButton("fAcceptButton", "Pair",
104 new BMessage(skMessageAcceptButton));
105
106 fCancelButton = new BButton("fCancelButton", "Cancel",
107 new BMessage(skMessageCancelButton));
108
109 AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
110 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0)
111 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 8)
112 .Add(fIcon)
113 )
114 .Add(BGroupLayoutBuilder(B_VERTICAL, 0)
115 .Add(fMessage)
116 .Add(fMessage2)
117 .AddGlue()
118 )
119 )
120 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0)
121 .Add(fDeviceLabel)
122 .AddGlue()
123 .Add(fDeviceText)
124 )
125 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0)
126 .Add(fAddressLabel)
127 .AddGlue()
128 .Add(fAddressText)
129 )
130 .AddGlue()
131 .Add(fPincodeText)
132 .AddGlue()
133 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
134 .AddGlue()
135 .Add(fCancelButton)
136 .Add(fAcceptButton)
137 )
138 .SetInsets(8, 8, 8, 8)
139 );
140 }
141
142
143 void
MessageReceived(BMessage * msg)144 PincodeWindow::MessageReceived(BMessage* msg)
145 {
146 switch (msg->what)
147 {
148 case skMessageAcceptButton:
149 {
150 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
151 BMessage reply;
152 size_t size;
153 int8 bt_status = BT_ERROR;
154
155 void* command = buildPinCodeRequestReply(fBdaddr,
156 strlen(fPincodeText->Text()),
157 (char*)fPincodeText->Text(), &size);
158
159 if (command == NULL) {
160 break;
161 }
162
163 request.AddInt32("hci_id", fHid);
164 request.AddData("raw command", B_ANY_TYPE, command, size);
165 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
166 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
167 OCF_PIN_CODE_REPLY));
168
169 // we reside in the server
170 if (be_app_messenger.SendMessage(&request, &reply) == B_OK) {
171 if (reply.FindInt8("status", &bt_status ) == B_OK) {
172 PostMessage(B_QUIT_REQUESTED);
173 }
174 // TODO: something failed here
175 }
176 break;
177 }
178
179 case skMessageCancelButton:
180 {
181 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
182 BMessage reply;
183 size_t size;
184 int8 bt_status = BT_ERROR;
185
186 void* command = buildPinCodeRequestNegativeReply(fBdaddr, &size);
187
188 if (command == NULL) {
189 break;
190 }
191
192 request.AddInt32("hci_id", fHid);
193 request.AddData("raw command", B_ANY_TYPE, command, size);
194 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
195 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
196 OCF_PIN_CODE_NEG_REPLY));
197
198 if (be_app_messenger.SendMessage(&request, &reply) == B_OK) {
199 if (reply.FindInt8("status", &bt_status ) == B_OK ) {
200 PostMessage(B_QUIT_REQUESTED);
201 }
202 // TODO: something failed here
203 }
204 break;
205 }
206
207 default:
208 BWindow::MessageReceived(msg);
209 break;
210 }
211 }
212
213
214 bool
QuitRequested()215 PincodeWindow::QuitRequested()
216 {
217 return BWindow::QuitRequested();
218 }
219
220
221 void
SetBDaddr(BString address)222 PincodeWindow::SetBDaddr(BString address)
223 {
224 fAddressText->SetText(address);
225 }
226
227 } /* end namespace Bluetooth */
228