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