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 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 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 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 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 215 PincodeWindow::QuitRequested() 216 { 217 return BWindow::QuitRequested(); 218 } 219 220 221 void 222 PincodeWindow::SetBDaddr(BString address) 223 { 224 fAddressText->SetText(address); 225 } 226 227 } /* end namespace Bluetooth */ 228