xref: /haiku/src/kits/bluetooth/UI/PincodeWindow.cpp (revision 03187b607b2b5eec7ee059f1ead09bdba14991fb)
1 /*
2  * Copyright 2007-2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <malloc.h>
9 
10 #include <String.h>
11 #include <Message.h>
12 #include <Application.h>
13 
14 #include <Button.h>
15 #include <GroupLayoutBuilder.h>
16 #include <InterfaceDefs.h>
17 #include <SpaceLayoutItem.h>
18 #include <StringView.h>
19 #include <TextControl.h>
20 
21 #include <bluetooth/RemoteDevice.h>
22 #include <bluetooth/LocalDevice.h>
23 #include <bluetooth/bdaddrUtils.h>
24 #include <bluetooth/bluetooth_error.h>
25 
26 #include <bluetooth/HCI/btHCI_command.h>
27 #include <bluetooth/HCI/btHCI_event.h>
28 
29 #include <PincodeWindow.h>
30 #include <bluetoothserver_p.h>
31 #include <CommandManager.h>
32 
33 
34 #define H_SEPARATION  15
35 #define V_SEPARATION  10
36 #define BD_ADDR_LABEL "BD_ADDR: "
37 
38 static const uint32 skMessageAcceptButton = 'acCp';
39 static const uint32 skMessageCancelButton = 'mVch';
40 
41 
42 namespace Bluetooth {
43 
44 PincodeView::PincodeView(BRect rect)
45 	: BView(rect,"View", B_FOLLOW_NONE, B_WILL_DRAW )
46 {
47 
48 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
49 
50 	fMessage = new BStringView("Pincode", "Please enter the pincode ...",
51 		B_FOLLOW_ALL_SIDES);
52 	fMessage->SetFont(be_bold_font);
53 
54 	fRemoteInfo = new BStringView("bdaddr","BD_ADDR: ", B_FOLLOW_ALL_SIDES);
55 
56 	// TODO: Pincode cannot be more than 16 bytes
57 	fPincodeText = new BTextControl("pincode TextControl", "PIN code:", "5555", NULL);
58 
59 	fAcceptButton = new BButton("fAcceptButton", "Pair",
60 		new BMessage(skMessageAcceptButton));
61 
62 	fCancelButton = new BButton("fCancelButton", "Cancel",
63 		new BMessage(skMessageCancelButton));
64 
65 	SetLayout(new BGroupLayout(B_HORIZONTAL));
66 
67 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
68 				.Add(fMessage)
69 				.Add(fRemoteInfo)
70 				.Add(fPincodeText)
71 				.Add(BGroupLayoutBuilder(B_HORIZONTAL)
72 					.AddGlue()
73 					.Add(fCancelButton)
74 					.Add(fAcceptButton)
75 					.SetInsets(5, 5, 5, 5)
76 				)
77 			.Add(BSpaceLayoutItem::CreateVerticalStrut(0))
78 			.SetInsets(5, 5, 5, 5)
79 	);
80 
81 }
82 
83 
84 void PincodeView::SetBDaddr(const char* address)
85 {
86 	BString label;
87 
88 	label << BD_ADDR_LABEL << address;
89 	printf("++ %s\n",label.String());
90 	fRemoteInfo->SetText(label.String());
91 	fRemoteInfo->ResizeToPreferred();
92 	Invalidate();
93 
94 }
95 
96 #if 0
97 #pragma mark -
98 #endif
99 
100 PincodeWindow::PincodeWindow(bdaddr_t address, hci_id hid)
101 	: BWindow(BRect(700, 100, 900, 150), "Pincode Request",
102 		B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
103 		B_WILL_ACCEPT_FIRST_CLICK | B_NOT_ZOOMABLE | B_NOT_RESIZABLE,
104 		B_ALL_WORKSPACES), fBdaddr(address), fHid(hid)
105 {
106 	fView = new PincodeView(Bounds());
107 	AddChild(fView);
108 	// Readapt ourselves to what the view needs
109 	ResizeTo(fView->Bounds().Width(), fView->Bounds().Height());
110 
111 	// TODO: Get more info about device" ote name/features/encry/auth... etc
112 	fView->SetBDaddr(bdaddrUtils::ToString(fBdaddr));
113 }
114 
115 
116 PincodeWindow::PincodeWindow(RemoteDevice* rDevice)
117 	: BWindow(BRect(700, 100, 900, 150), "Pincode Request",
118 		B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
119 		B_WILL_ACCEPT_FIRST_CLICK | B_NOT_ZOOMABLE | B_NOT_RESIZABLE,
120 		B_ALL_WORKSPACES)
121 {
122 	fView = new PincodeView(Bounds());
123 	AddChild(fView);
124 	// Readapt ourselves to what the view needs
125 	ResizeTo(fView->Bounds().Width(), fView->Bounds().Height());
126 
127 	// TODO: Get more info about device" ote name/features/encry/auth... etc
128 	fView->SetBDaddr(bdaddrUtils::ToString(rDevice->GetBluetoothAddress()));
129 	fHid = (rDevice->GetLocalDeviceOwner())->ID();
130 }
131 
132 
133 void PincodeWindow::MessageReceived(BMessage *msg)
134 {
135 //	status_t err = B_OK;
136 
137 	switch(msg->what)
138 	{
139 		case skMessageAcceptButton:
140 		{
141 			BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
142 			BMessage reply;
143 			size_t size;
144 			int8 bt_status = BT_ERROR;
145 
146 			void* command = buildPinCodeRequestReply(fBdaddr,
147 				strlen(fView->fPincodeText->Text()),
148 				(char*)fView->fPincodeText->Text(), &size);
149 
150 			if (command == NULL) {
151 				break;
152 			}
153 
154 			request.AddInt32("hci_id", fHid);
155 			request.AddData("raw command", B_ANY_TYPE, command, size);
156 			request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
157 			request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
158 				OCF_PIN_CODE_REPLY));
159 
160 			// we reside in the server
161 			if (be_app_messenger.SendMessage(&request, &reply) == B_OK) {
162 				if (reply.FindInt8("status", &bt_status ) == B_OK ) {
163 					PostMessage(B_QUIT_REQUESTED);
164 				}
165 				// TODO: something failed here
166 			}
167 			break;
168 		}
169 
170 		case skMessageCancelButton:
171 		{
172 			BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
173 			BMessage reply;
174 			size_t size;
175 			int8 bt_status = BT_ERROR;
176 
177 			void* command = buildPinCodeRequestNegativeReply(fBdaddr, &size);
178 
179 			if (command == NULL) {
180 				break;
181 			}
182 
183 			request.AddInt32("hci_id", fHid);
184 			request.AddData("raw command", B_ANY_TYPE, command, size);
185 			request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
186 			request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
187 				OCF_PIN_CODE_NEG_REPLY));
188 
189 			if (be_app_messenger.SendMessage(&request, &reply) == B_OK) {
190 				if (reply.FindInt8("status", &bt_status ) == B_OK ) {
191 					PostMessage(B_QUIT_REQUESTED);
192 				}
193 				// TODO: something failed here
194 			}
195 			break;
196 		}
197 
198 		default:
199 			BWindow::MessageReceived(msg);
200 		break;
201 	}
202 }
203 
204 
205 bool PincodeWindow::QuitRequested()
206 {
207 	return BWindow::QuitRequested();
208 }
209 
210 }
211