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