xref: /haiku/src/kits/bluetooth/UI/PincodeWindow.cpp (revision 91cbfa855ee63eae9eff3131a2f8712b0333d395)
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