LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
c_bt.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
105 #include "lms2012.h"
106 #include "c_com.h"
107 #include "c_bt.h"
108 #include "c_i2c.h"
109 
110 #if (HARDWARE != SIMULATION)
111 
112  #include <stdio.h>
113  #include <fcntl.h>
114  #include <stdlib.h>
115  #include <unistd.h>
116  #include <string.h>
117  #include <signal.h>
118  #include <sys/mman.h>
119  #include <time.h>
120  #include <errno.h>
121 
122  #include <bluetooth/bluetooth.h>
123  #include <bluetooth/rfcomm.h>
124  #include <bluetooth/hci.h>
125  #include <bluetooth/hci_lib.h>
126  #include <bluetooth/sdp.h>
127  #include <bluetooth/sdp_lib.h>
128  #include <sys/socket.h>
129 
130  #include <dbus/dbus.h>
131 
132  #include <sys/poll.h>
133  #include <sys/ioctl.h>
134 
135 
136  typedef struct
137  {
138  bdaddr_t Addr;
139  UBYTE Port;
140  }PAIREDDEVINFO;
141 
142 
143  static PAIREDDEVINFO PairedDevInfo;
144 
145  BT_GLOBALS BtInstance;
146  static DBusConnection *conn;
147  static DBusMessage *reply;
148  static DBusMessage *RejectReply;
149 
150  static sdp_session_t *session = 0;
151 
152  static char *adapter_path = NULL;
153  char *agent_path = "/org/bluez/agent";
154  static UBYTE SimplePairingDisable[] = {0x06, 0x73, 0xFF};
155  static UBYTE SimplePairingEnable[] = {0x06, 0x7B, 0xFF};
156  static UBYTE ExtendedFeaturesDisable[] = {0x07, 0x03, 0xFF};
157  static UBYTE ExtendedFeaturesEnable[] = {0x07, 0x83, 0xFF};
158 
159  static volatile sig_atomic_t __io_canceled = 0;
160  static volatile sig_atomic_t __io_terminated = 0;
161 
162 #else
163 
165 
166  void setOutputInstance(BT_GLOBALS * _Instance)
167  {
168  gBtInstance= _Instance;
169  }
170 
172  {
173  return gBtInstance;
174  }
175 
176 #endif
177 
178 
179 #define LEGO_BUNDLE_SEED_ID "9RNK8ZF528"
180 #define LEGO_BUNDLE_ID "com.lego.lms"
181 
182 enum
183 {
189  TURN_ON = 5,
190  TURN_OFF = 6,
191  RESTART = 7,
193 };
194 
195 enum
196 {
201 };
202 
203 /* Constants related to Decode mode */
204 enum
205 {
206  MODE1 = 0,
207  MODE2 = 1
208 };
209 
210 
211 UBYTE BtConnectTo(UBYTE Port, bdaddr_t BtAddr);
212 void BtTxMsgs(void);
213 void BtSetup(UBYTE State);
214 UWORD cBtHandleHCI(void);
215 void BtDisconnectAll(void);
217 
218 UBYTE cBtFindDevChNo(UBYTE ChNo, UBYTE *pIndex);
219 UBYTE cBtFindDevConnHandle(UBYTE ConnHandle, UBYTE *pIndex);
220 UBYTE cBtFindDevAdr(bdaddr_t *pAdr, UBYTE *pIndex);
221 void cBtSetDevConnectedStatus(UBYTE Index);
222 void cBtCloseDevConnection(UBYTE Index);
223 UBYTE cBtFindSearchAdr(bdaddr_t *pAdr, UBYTE *pIndex);
226 void BtCloseBtSocket(SLONG *pBtSocket);
227 
228 static char *get_adapter_path(DBusConnection *conn, const char *adapter);
229 static DBusHandlerResult agent_message(DBusConnection *conn, DBusMessage *msg, void *data);
230 static int register_agent(DBusConnection *conn, const char *adapter_path, const char *agent_path, const char *capabilities);
231 static DBusHandlerResult agent_filter(DBusConnection *conn, DBusMessage *msg, void *data);
232 static DBusHandlerResult request_pincode_message(DBusConnection *conn, DBusMessage *msg, void *data);
233 static char *get_default_adapter_path(DBusConnection *conn);
234 static void sig_term(int sig);
235 static int unregister_agent(DBusConnection *conn, const char *adapter_path, const char *agent_path);
236 
237 static int RemoveDevice(DBusConnection *conn, char *Device);
238 void cBtStrNoColonToBa(UBYTE *pBtStrAddr, bdaddr_t *pAddr);
239 
240 void DecodeMode1(UBYTE BufNo);
241 void DecodeMode2(void);
242 
243 void BtClose(void);
244 UBYTE BtIssueHciVisible(UBYTE Visible, UBYTE Page);
245 
246 
247 
249 {
250  int dev_id;
251 
252  dev_id = hci_get_route(NULL);
253  BtInstance.HciSocket.Socket = hci_open_dev( dev_id );
254  if (dev_id < 0 || BtInstance.HciSocket.Socket < 0)
255  {
256  perror("Can't open socket");
257  return;
258  }
259 }
260 
261 void BtSetupPinEvent(void)
262 {
263  struct hci_filter flt;
264 
265  hci_filter_clear(&flt);
266  hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
267  hci_filter_set_event(EVT_CONN_COMPLETE, &flt);
268  hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt);
269  hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt);
270  hci_filter_set_event(EVT_ENCRYPT_CHANGE, &flt);
271  hci_filter_set_event(EVT_CMD_COMPLETE, &flt);
272  hci_filter_set_event(EVT_CMD_STATUS, &flt);//
273 
274  hci_filter_set_event(EVT_INQUIRY_RESULT, &flt);
275  hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt);
276  hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt);
277  hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt);
278  hci_filter_set_event(EVT_PIN_CODE_REQ, &flt);
279 
280  hci_filter_set_event(EVT_CONN_REQUEST, &flt);
281  hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt);
282 
283  if (setsockopt(BtInstance.HciSocket.Socket, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0)
284  {
285  perror("Can't set HCI filter");
286  return;
287  }
288  BtInstance.HciSocket.p.fd = BtInstance.HciSocket.Socket;
289  BtInstance.HciSocket.p.events = POLLIN | POLLERR | POLLHUP;
290 
291 
292 }
293 
294 
295 void SetupListeningSocket(int *Socket)
296 {
297  SLONG TmpSockFlags;
298  struct bt_security sec;
299 
300  memset(&sec, 0, sizeof(sec));
301  sec.level = 3;
302 
303  int lm_map[] =
304  {
305  0,
306  RFCOMM_LM_AUTH,
307  RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT,
308  RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE,
309  }, opt = lm_map[sec.level];
310 
311  *Socket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
312  BtInstance.ListenSocket.loc_addr.rc_family = AF_BLUETOOTH;
313  BtInstance.ListenSocket.loc_addr.rc_bdaddr = *BDADDR_ANY;
314  BtInstance.ListenSocket.loc_addr.rc_channel = 1;
315  bind(*Socket, (struct sockaddr *)&(BtInstance.ListenSocket.loc_addr), sizeof(BtInstance.ListenSocket.loc_addr));
316 
317  setsockopt(*Socket, SOL_BLUETOOTH, BT_SECURITY, &sec, sizeof(sec));
318  setsockopt(*Socket, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt));
319 
320  TmpSockFlags = fcntl(*Socket, F_GETFL, 0);
321  fcntl(*Socket, F_SETFL, TmpSockFlags | O_NONBLOCK);
322 
323  listen(*Socket,1);
324 }
325 
326 
327 void BtClearChBuf(UBYTE ChNo)
328 {
329  BtInstance.BtCh[ChNo].Status = CH_FREE;
330  BtInstance.BtCh[ChNo].ReadBuf.Status = READ_BUF_EMPTY;
331  BtInstance.BtCh[ChNo].ReadBuf.InPtr = 0;
332  BtInstance.BtCh[ChNo].ReadBuf.OutPtr = 0;
333 
334  if (0 == ChNo)
335  {
336  BtInstance.Mode2Buf.Status = MSG_BUF_EMPTY;
337  BtInstance.Mode2Buf.InPtr = 0;
338  BtInstance.Mode2Buf.OutPtr = 0;
339  }
340 
341  BtInstance.BtCh[ChNo].MsgBuf.Status = MSG_BUF_EMPTY;
342  BtInstance.BtCh[ChNo].MsgBuf.InPtr = 0;
343  BtInstance.BtCh[ChNo].MsgBuf.LargeMsg = FALSE;
344  BtInstance.BtCh[ChNo].MsgBuf.MsgLen = 0;
345  BtInstance.BtCh[ChNo].MsgBuf.RemMsgLen = 0;
346 }
347 
348 
349 void BtInit(char* pName)
350 {
351  int File;
352  int Tmp;
353  FILE *FSer;
354 
355  BtInstance.OnOffSeqCnt = 0;
356  BtInstance.NoOfConnDevs = 0;
357 
358  // Load all persistent variables
359  FSer = fopen("./settings/BTser","r");
360  if (FSer != NULL)
361  {
362  fgets((char*)&(BtInstance.Adr[0]), (int)13, FSer);
363  fclose (FSer);
364  }
365  else
366  {
367  //Error - Fil with zeros
368  strcpy((char*)&(BtInstance.Adr[0]), "000000000000");
369  }
370 
371  File = open(NONVOL_BT_DATA,O_RDWR,0666);
372  if (File >= MIN_HANDLE)
373  {
374  // Reads both Visible and ON/OFF status
375  if (read(File,(UBYTE*)&BtInstance.NonVol, sizeof(BtInstance.NonVol)) != sizeof(BtInstance.NonVol))
376  {
377  close (File);
378  File = -1;
379  }
380  else
381  {
382  close (File);
383  }
384  }
385  else
386  {
387  // Default settings
388  BtInstance.NonVol.Visible = TRUE;
389  BtInstance.NonVol.On = FALSE;
390  BtInstance.NonVol.DecodeMode = MODE1;
391 
392  snprintf((char*)&BtInstance.NonVol.BundleID[0], MAX_BUNDLE_ID_SIZE, "%s", (char*)LEGO_BUNDLE_ID);
393  snprintf((char*)&BtInstance.NonVol.BundleSeedID[0], MAX_BUNDLE_SEED_ID_SIZE, "%s", (char*)LEGO_BUNDLE_SEED_ID);
394 
395  for(Tmp = 0; Tmp < MAX_DEV_TABLE_ENTRIES; Tmp++)
396  {
397  BtInstance.NonVol.DevList[Tmp].Status = DEV_EMPTY;
398  }
399  BtInstance.NonVol.DevListEntries = 0;
400  }
401 
402  BtInstance.HciSocket.Socket = -1;
403 
404  if (TRUE == BtInstance.NonVol.On)
405  {
406  BtInstance.State = TURN_ON;
407  BtSetup(TURN_ON);
408  }
409  else
410  {
411  BtInstance.State = TURN_OFF;
412  BtSetup(TURN_OFF);
413  }
414 
415  BtInstance.Events = 0;
416  BtInstance.TrustedDev.Status = FALSE;
417 
418  BtInstance.BtName[0] = 0;
419  snprintf((char*)&(BtInstance.BtName[0]), vmBRICKNAMESIZE, "%s",(char*)pName);
420  bacpy(&(BtInstance.TrustedDev.Adr), BDADDR_ANY); // BDADDR_ANY = all zeros!
421 
422  I2cInit(&(BtInstance.BtCh[0].ReadBuf), &(BtInstance.Mode2WriteBuf), (char *)&(BtInstance.NonVol.BundleID[0]), (char*)&(BtInstance.NonVol.BundleSeedID[0]));
423 }
424 
425 
426 void BtExit(void)
427 {
428  int File;
429 
430  BtClose();
431 
432  File = open(NONVOL_BT_DATA,O_CREAT | O_WRONLY | O_TRUNC,0666);
433  if (File >= MIN_HANDLE)
434  {
435  write(File,(UBYTE*)&BtInstance.NonVol, sizeof(BtInstance.NonVol));
436  close (File);
437  }
438 
439  I2cExit();
440 }
441 
442 
443 void BtCloseBtSocket(SLONG *pBtSocket)
444 {
445  if (MIN_HANDLE <= *pBtSocket)
446  {
447  close(*pBtSocket);
448  *pBtSocket = -1;
449  }
450 }
451 
452 
453 void BtCloseCh(UBYTE ChIndex)
454 {
455  if (CH_FREE != BtInstance.BtCh[ChIndex].Status)
456  {
457  BtInstance.BtCh[ChIndex].Status = CH_FREE;
458  }
459 
460  BtCloseBtSocket(&(BtInstance.BtCh[ChIndex].BtSocket.Socket));
461 
462  if (0 < BtInstance.NoOfConnDevs)
463  {
464  BtInstance.NoOfConnDevs--;
465  if (0 == BtInstance.NoOfConnDevs)
466  {
468  }
469  }
470  else
471  {
472  if ((I_AM_MASTER == BtInstance.State) || (I_AM_SLAVE == BtInstance.State))
473  {
474  //Ensure going back to idle if only pairing (no application running on remote device)
476  }
477  }
478 }
479 
480 
481 void BtDisconnectAll(void)
482 {
483  UBYTE Tmp;
484 
485  for(Tmp = 0; Tmp < MAX_DEV_TABLE_ENTRIES; Tmp++)
486  {
487  BtInstance.NonVol.DevList[Tmp].Connected = FALSE;
488  }
489 
490  for(Tmp = 0; Tmp < NO_OF_BT_CHS; Tmp++)
491  {
492  if (CH_FREE != BtInstance.BtCh[Tmp].Status)
493  {
494  BtCloseCh(Tmp);
495  }
496  }
497 }
498 
499 
511 void BtSetup(UBYTE State)
512 {
513  BtInstance.OldState = BtInstance.State;
514  BtInstance.State = State;
515  switch(State)
516  {
517  case TURN_ON:
518  {
519  BtInstance.OnOffSeqCnt = 0;
520  }
521  break;
522 
523  case TURN_OFF:
524  {
525  BtInstance.OnOffSeqCnt = 0;
526  }
527  break;
528 
529  case I_AM_IN_IDLE:
530  {
531  // Stop Mode2 decoding - can be called even if not used
532  I2cStop();
534  BtInstance.PageState = SCAN_PAGE;
535  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
536  BtInstance.HciSocket.Busy |= HCI_VISIBLE;
537  }
538  break;
539 
540  case I_AM_MASTER:
541  {
542  // Cannot be accepting other incoming connections.. scatter-net not supported
543  BtCloseBtSocket(&(BtInstance.ListenSocket.Socket));
544  }
545  break;
546 
547  case I_AM_SLAVE:
548  {
549  // Cannot be accepting other incoming connections.. scatter-net not supported
550  BtCloseBtSocket(&(BtInstance.ListenSocket.Socket));
551  BtClearChBuf(0);
552  }
553  break;
554 
555  case I_AM_SCANNING:
556  {
557  UBYTE TmpCnt;
558  inquiry_cp cp;
559  write_inquiry_mode_cp cmp;
560 
561  // Do not accept incoming connects during scan
562  BtIssueHciVisible(BtInstance.NonVol.Visible, 0);
563  BtCloseBtSocket(&(BtInstance.ListenSocket.Socket));
564 
565  cmp.mode = 0x01;
566  if (hci_send_cmd(BtInstance.HciSocket.Socket, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, WRITE_INQUIRY_MODE_RP_SIZE, &cmp) < 0)
567  {
568  #ifdef DEBUG
569  printf("Can't set inquiry mode");
570  #endif
571 
572  return;
573  }
574 
575  // This is general inquiry LAP
576  memset (&cp, 0, sizeof(cp));
577  cp.lap[2] = 0x9e;
578  cp.lap[1] = 0x8b;
579  cp.lap[0] = 0x33;
580  cp.num_rsp = 0;
581  cp.length = 0x0F;
582 
583  #ifdef DEBUG
584  printf("Starting inquiry with RSSI...\n");
585  #endif
586 
587  if (hci_send_cmd (BtInstance.HciSocket.Socket, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &cp) < 0)
588  {
589  #ifdef DEBUG
590  printf("Can't start inquiry");
591  #endif
592  return;
593  }
594 
595  // Clear the search list
596  for(TmpCnt = 0; TmpCnt < MAX_DEV_TABLE_ENTRIES; TmpCnt++)
597  {
598  BtClearSearchListEntry(TmpCnt);
599  }
600 
601  BtInstance.NoOfFoundNames = 0;
602  BtInstance.NoOfFoundDev = 0;
603  BtInstance.SearchIndex = 0;
604  BtInstance.State = I_AM_SCANNING;
605  BtInstance.ScanState = SCAN_INQ_STATE;
606  }
607  break;
608 
609  case STOP_SCANNING:
610  {
611  }
612  break;
613 
614  case BLUETOOTH_OFF:
615  {
616  }
617  break;
618 
619  case RESTART:
620  {
621  BtInstance.OnOffSeqCnt = 0;
622  BtInstance.RestartSeqCnt = 0;
623  }
624  break;
625  }
626 }
627 
628 
630 {
631  UWORD RtnVal;
632  remote_name_req_cp cp;
633 
634  RtnVal = TRUE;
635 
636  memset(&cp, 0, sizeof(cp));
637  bacpy(&cp.bdaddr, &BtInstance.SearchList[BtInstance.SearchIndex].Adr);
638  cp.pscan_rep_mode = 0x02;
639 
640  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, REMOTE_NAME_REQ_CP_SIZE, &cp);
641 
642  return(RtnVal);
643 }
644 
645 
647 {
648  UBYTE RtnVal;
649 
650  if(((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy)) && (BLUETOOTH_OFF != BtInstance.State))
651  {
652  BtInstance.HciSocket.Busy = HCI_SCAN;
654  RtnVal = OK;
655  }
656  else
657  {
658  RtnVal = FAIL;
659  }
660  return(RtnVal);
661 }
662 
663 
665 {
666  UBYTE RtnVal;
667  if (HCI_SCAN == BtInstance.HciSocket.Busy)
668  {
669  switch(BtInstance.ScanState)
670  {
671  case SCAN_OFF:
672  {
673  BtInstance.HciSocket.Busy = HCI_IDLE;
674  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
675  }
676  break;
677  case SCAN_INQ_STATE:
678  {
679  hci_send_cmd (BtInstance.HciSocket.Socket, OGF_LINK_CTL, OCF_INQUIRY_CANCEL, 0, NULL);
680  }
681  break;
682  case SCAN_NAME_STATE:
683  {
684  BtInstance.ScanState = SCAN_OFF;
685  }
686  break;
687  }
688  RtnVal = OK;
689  }
690  else
691  {
692  if((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy))
693  {
694  BtInstance.HciSocket.Busy = HCI_IDLE;
695  RtnVal = OK;
696  }
697  else
698  {
699  RtnVal = FAIL;
700  }
701  }
702  return(RtnVal);
703 }
704 
705 
706 UWORD cBtReadCh0(UBYTE *pBuf, UWORD Length)
707 {
708  MSGBUF *pMsgBuf;
709  UWORD RtnLen = 0;
710 
711  pMsgBuf = &(BtInstance.BtCh[0].MsgBuf);
712 
713  if (MSG_BUF_FULL == pMsgBuf->Status)
714  {
715  #ifdef DEBUG
716  printf("\r\n MSG_BUF_FULL - Reading from cCom on Bt Channel 0 number of bytes = %d\r\n",pMsgBuf->InPtr);
717  #endif
718 
719  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
720  RtnLen = pMsgBuf->InPtr;
721  pMsgBuf->Status = MSG_BUF_EMPTY;
722  }
723  return(RtnLen);
724 }
725 
726 
727 UWORD cBtReadCh1(UBYTE *pBuf, UWORD Length)
728 {
729  MSGBUF *pMsgBuf;
730  UWORD RtnLen = 0;
731 
732  pMsgBuf = &(BtInstance.BtCh[1].MsgBuf);
733 
734  if (MSG_BUF_FULL == pMsgBuf->Status)
735  {
736 
737  #ifdef DEBUG
738  printf("\r\n MSG_BUF_FULL on Bt Channel 1 %d bytes copied\r\n",pMsgBuf->InPtr);
739  #endif
740 
741  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
742  RtnLen = pMsgBuf->InPtr;
743  pMsgBuf->Status = MSG_BUF_EMPTY;
744  }
745  return(RtnLen);
746 }
747 
748 
749 UWORD cBtReadCh2(UBYTE *pBuf, UWORD Length)
750 {
751  MSGBUF *pMsgBuf;
752  UWORD RtnLen = 0;
753 
754  pMsgBuf = &(BtInstance.BtCh[2].MsgBuf);
755 
756  if (MSG_BUF_FULL == pMsgBuf->Status)
757  {
758 
759  #ifdef DEBUG
760  printf("\r\n MSG_BUF_FULL on Bt Channel 1\r\n");
761  #endif
762 
763  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
764  RtnLen = pMsgBuf->InPtr;
765  pMsgBuf->Status = MSG_BUF_EMPTY;
766  }
767  return(RtnLen);
768 }
769 
770 
771 UWORD cBtReadCh3(UBYTE *pBuf, UWORD Length)
772 {
773  MSGBUF *pMsgBuf;
774  UWORD RtnLen = 0;
775 
776  pMsgBuf = &(BtInstance.BtCh[3].MsgBuf);
777 
778  if (MSG_BUF_FULL == pMsgBuf->Status)
779  {
780 
781  #ifdef DEBUG
782  printf("\r\n MSG_BUF_FULL on Bt Channel 1\r\n");
783  #endif
784 
785  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
786  RtnLen = pMsgBuf->InPtr;
787  pMsgBuf->Status = MSG_BUF_EMPTY;
788  }
789  return(RtnLen);
790 }
791 
792 
793 UWORD cBtReadCh4(UBYTE *pBuf, UWORD Length)
794 {
795  MSGBUF *pMsgBuf;
796  UWORD RtnLen = 0;
797 
798  pMsgBuf = &(BtInstance.BtCh[4].MsgBuf);
799 
800  if (MSG_BUF_FULL == pMsgBuf->Status)
801  {
802 
803  #ifdef DEBUG
804  printf("\r\n MSG_BUF_FULL on Bt Channel 1\r\n");
805  #endif
806 
807  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
808  RtnLen = pMsgBuf->InPtr;
809  pMsgBuf->Status = MSG_BUF_EMPTY;
810  }
811  return(RtnLen);
812 }
813 
814 
815 UWORD cBtReadCh5(UBYTE *pBuf, UWORD Length)
816 {
817  MSGBUF *pMsgBuf;
818  UWORD RtnLen = 0;
819 
820  pMsgBuf = &(BtInstance.BtCh[5].MsgBuf);
821 
822  if (MSG_BUF_FULL == pMsgBuf->Status)
823  {
824 
825  #ifdef DEBUG
826  printf("\r\n MSG_BUF_FULL on Bt Channel 1\r\n");
827  #endif
828 
829  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
830  RtnLen = pMsgBuf->InPtr;
831  pMsgBuf->Status = MSG_BUF_EMPTY;
832  }
833  return(RtnLen);
834 }
835 
836 
837 UWORD cBtReadCh6(UBYTE *pBuf, UWORD Length)
838 {
839  MSGBUF *pMsgBuf;
840  UWORD RtnLen = 0;
841 
842  pMsgBuf = &(BtInstance.BtCh[6].MsgBuf);
843 
844  if (MSG_BUF_FULL == pMsgBuf->Status)
845  {
846 
847  #ifdef DEBUG
848  printf("\r\n MSG_BUF_FULL on Bt Channel 1\r\n");
849  #endif
850 
851  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
852  RtnLen = pMsgBuf->InPtr;
853  pMsgBuf->Status = MSG_BUF_EMPTY;
854  }
855  return(RtnLen);
856 }
857 
858 UWORD cBtReadCh7(UBYTE *pBuf, UWORD Length)
859 {
860  MSGBUF *pMsgBuf;
861  UWORD RtnLen = 0;
862 
863  pMsgBuf = &(BtInstance.BtCh[7].MsgBuf);
864 
865  if (MSG_BUF_FULL == pMsgBuf->Status)
866  {
867 
868  #ifdef DEBUG
869  printf("\r\n MSG_BUF_FULL on Bt Channel 1\r\n");
870  #endif
871 
872  memcpy(pBuf, pMsgBuf->Buf, (pMsgBuf->InPtr));
873  RtnLen = pMsgBuf->InPtr;
874  pMsgBuf->Status = MSG_BUF_EMPTY;
875  }
876  return(RtnLen);
877 }
878 
880 {
881  if (MODE1 == BtInstance.NonVol.DecodeMode)
882  {
883  DecodeMode1(BufNo);
884  }
885  else
886  {
887  // Need to decode mode2 before decoding mode1
888  DecodeMode2();
889  }
890 }
891 
892 
893 void DecodeMode2(void)
894 {
895  UWORD BytesAccepted;
896  SLONG AvailBytes;
897 
898  // Buffer is dedicated to mode2 only
899  // Only one bluetooth connection is valid at a time
900 
901  AvailBytes = (BtInstance.Mode2Buf.InPtr - BtInstance.Mode2Buf.OutPtr); /* How many bytes is ready to be read */
902  if (AvailBytes)
903  {
904  BytesAccepted = DataToMode2Decoding(&(BtInstance.Mode2Buf.Buf[0]), AvailBytes); /* Transfer bytes to mode2 decoding */
905 
906  if (BytesAccepted == AvailBytes)
907  {
908  BtInstance.Mode2Buf.OutPtr = 0;
909  BtInstance.Mode2Buf.InPtr = 0;
910  BtInstance.Mode2Buf.Status = READ_BUF_EMPTY;
911  }
912  else
913  {
914  BtInstance.Mode2Buf.OutPtr += BytesAccepted;
915  }
916  }
917 }
918 
919 
920 void DecodeMode1(UBYTE BufNo)
921 {
922  SLONG AvailBytes;
923  READBUF *pReadBuf;
924  MSGBUF *pMsgBuf;
925 
926  #ifdef DEBUG
927  SLONG Test;
928  #endif
929 
930  /* 1. Check if there is more data to interpret */
931  /* 2. Check the status of the active buffer */
932  pReadBuf = &(BtInstance.BtCh[BufNo].ReadBuf); // Source buffer
933  pMsgBuf = &(BtInstance.BtCh[BufNo].MsgBuf); // Destination Buffer
934 
935  AvailBytes = (pReadBuf->InPtr - pReadBuf->OutPtr); /* How many bytes is ready to be read */
936 
937  #ifdef DEBUG
938  printf("\r\nDecode mode 1: Avail bytes = %d MsgBuf status = %d\r\n",AvailBytes,pMsgBuf->Status);
939  #endif
940 
941  switch(pMsgBuf->Status)
942  {
943  case MSG_BUF_EMPTY:
944  {
945  // Message buffer is empty
946  pMsgBuf->InPtr = 0;
947 
948  if(TRUE == pMsgBuf->LargeMsg)
949  {
950  pMsgBuf->Status = MSG_BUF_BODY;
951  }
952  else
953  {
954  if (2 <= AvailBytes)
955  {
956  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), 2);
957  pMsgBuf->InPtr += 2;
958  pReadBuf->OutPtr += 2;
959  AvailBytes -= 2;
960 
961  pMsgBuf->RemMsgLen = (int)(pMsgBuf->Buf[0]) + ((int)(pMsgBuf->Buf[1]) * 256);
962  pMsgBuf->MsgLen = pMsgBuf->RemMsgLen;
963 
964  if (0 != pMsgBuf->RemMsgLen)
965  {
966 
967  if (pMsgBuf->RemMsgLen <= AvailBytes)
968  {
969  // Rest of message is received move it to the message buffer
970  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), (pMsgBuf->RemMsgLen));
971 
972  AvailBytes -= (pMsgBuf->RemMsgLen);
973  pReadBuf->OutPtr += (pMsgBuf->RemMsgLen);
974  pMsgBuf->InPtr += (pMsgBuf->RemMsgLen);
975  pMsgBuf->Status = MSG_BUF_FULL;
976 
977  #ifdef DEBUG
978  printf(" Message is received from MSG_BUF_EMPTY: ");
979  for (Test = 0; Test < ((pMsgBuf->MsgLen) + 2); Test++)
980  {
981  printf("%02X ", pMsgBuf->Buf[Test]);
982  }
983  printf(" \r\n");
984  #endif
985 
986  if (0 == AvailBytes)
987  {
988  // Read buffer is empty
989  pReadBuf->OutPtr = 0;
990  pReadBuf->InPtr = 0;
991  pReadBuf->Status = READ_BUF_EMPTY;
992  }
993  }
994  else
995  {
996  // Still some bytes needed to be received
997  // So Read buffer is emptied
998  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), AvailBytes);
999 
1000  pMsgBuf->Status = MSG_BUF_BODY;
1001  pMsgBuf->RemMsgLen -= AvailBytes;
1002  pMsgBuf->InPtr += AvailBytes;
1003 
1004  pReadBuf->OutPtr = 0;
1005  pReadBuf->InPtr = 0;
1006  pReadBuf->Status = READ_BUF_EMPTY;
1007  }
1008  }
1009  else
1010  {
1011  if (0 == AvailBytes)
1012  {
1013  // Read buffer is empty
1014  pReadBuf->OutPtr = 0;
1015  pReadBuf->InPtr = 0;
1016  pReadBuf->Status = READ_BUF_EMPTY;
1017  }
1018  }
1019  }
1020  else
1021  {
1022  // Only one byte has been received - first byte of length info
1023  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), 1);
1024  pReadBuf->OutPtr++;
1025  pMsgBuf->InPtr++;
1026 
1027  pMsgBuf->RemMsgLen = (int)(pMsgBuf->Buf[0]);
1028  pMsgBuf->Status = MSG_BUF_LEN;
1029 
1030  pReadBuf->OutPtr = 0;
1031  pReadBuf->InPtr = 0;
1032  pReadBuf->Status = READ_BUF_EMPTY;
1033  }
1034  }
1035  }
1036  break;
1037 
1038  case MSG_BUF_LEN:
1039  {
1040  // Read the last length bytes
1041  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), 1);
1042  pMsgBuf->InPtr++;
1043  pReadBuf->OutPtr++;
1044  AvailBytes--;
1045 
1046  pMsgBuf->RemMsgLen = (int)(pMsgBuf->Buf[0]) + ((int)(pMsgBuf->Buf[1]) * 256);
1047  pMsgBuf->MsgLen = pMsgBuf->RemMsgLen;
1048 
1049  if (0 != pMsgBuf->RemMsgLen)
1050  {
1051 
1052  if ((pMsgBuf->RemMsgLen) <= AvailBytes)
1053  {
1054  // rest of message is received move it to the message buffer
1055  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), (pMsgBuf->RemMsgLen));
1056 
1057  AvailBytes -= (pMsgBuf->RemMsgLen);
1058  pReadBuf->OutPtr += (pMsgBuf->RemMsgLen);
1059  pMsgBuf->InPtr += (pMsgBuf->RemMsgLen);
1060  pMsgBuf->Status = MSG_BUF_FULL;
1061 
1062  #ifdef DEBUG
1063  printf(" Message is received from MSG_BUF_EMPTY: ");
1064  for (Test = 0; Test < ((pMsgBuf->MsgLen) + 2); Test++)
1065  {
1066  printf("%02X ", pMsgBuf->Buf[Test]);
1067  }
1068  printf(" \r\n");
1069  #endif
1070 
1071  if (0 == AvailBytes)
1072  {
1073  // Read buffer is empty
1074  pReadBuf->OutPtr = 0;
1075  pReadBuf->InPtr = 0;
1076  pReadBuf->Status = READ_BUF_EMPTY;
1077  }
1078  }
1079  else
1080  {
1081  // Still some bytes needed to be received
1082  // So receive buffer is emptied
1083  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), AvailBytes);
1084 
1085  pMsgBuf->Status = MSG_BUF_BODY;
1086  pMsgBuf->RemMsgLen -= AvailBytes;
1087  pMsgBuf->InPtr += AvailBytes;
1088 
1089  pReadBuf->OutPtr = 0;
1090  pReadBuf->InPtr = 0;
1091  pReadBuf->Status = READ_BUF_EMPTY;
1092  }
1093  }
1094  else
1095  {
1096  if (0 == AvailBytes)
1097  {
1098  // Read buffer is empty
1099  pReadBuf->OutPtr = 0;
1100  pReadBuf->InPtr = 0;
1101  pReadBuf->Status = READ_BUF_EMPTY;
1102 
1103  pMsgBuf->Status = MSG_BUF_EMPTY;
1104  }
1105  }
1106  }
1107  break;
1108 
1109  case MSG_BUF_BODY:
1110  {
1111  ULONG BufFree;
1112 
1113  BufFree = (sizeof(pMsgBuf->Buf) - (pMsgBuf->InPtr));
1114  if (BufFree < (pMsgBuf->RemMsgLen))
1115  {
1116 
1117  pMsgBuf->LargeMsg = TRUE;
1118 
1119  //This is large message
1120  if (BufFree >= AvailBytes)
1121  {
1122  //The available bytes can be included in this buffer
1123  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), AvailBytes);
1124 
1125  //Buffer is still not full
1126  pMsgBuf->Status = MSG_BUF_BODY;
1127  pMsgBuf->RemMsgLen -= AvailBytes;
1128  pMsgBuf->InPtr += AvailBytes;
1129 
1130  //Readbuffer has been completely emptied
1131  pReadBuf->OutPtr = 0;
1132  pReadBuf->InPtr = 0;
1133  pReadBuf->Status = READ_BUF_EMPTY;
1134  }
1135  else
1136  {
1137  //The available bytes cannot all be included in the buffer
1138  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), BufFree);
1139  pReadBuf->OutPtr += BufFree;
1140  pMsgBuf->InPtr += BufFree;
1141  pMsgBuf->RemMsgLen -= BufFree;
1142  pMsgBuf->Status = MSG_BUF_FULL;
1143  }
1144  }
1145  else
1146  {
1147  pMsgBuf->LargeMsg = FALSE;
1148 
1149  if ((pMsgBuf->RemMsgLen) <= AvailBytes)
1150  {
1151  // rest of message is received move it to the message buffer
1152  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), (pMsgBuf->RemMsgLen));
1153 
1154  AvailBytes -= (pMsgBuf->RemMsgLen);
1155  pReadBuf->OutPtr += (pMsgBuf->RemMsgLen);
1156  pMsgBuf->InPtr += (pMsgBuf->RemMsgLen);
1157  pMsgBuf->Status = MSG_BUF_FULL;
1158 
1159  #ifdef DEBUG
1160  printf(" Message is received from MSG_BUF_EMPTY: ");
1161  for (Test = 0; Test < ((pMsgBuf->MsgLen) + 2); Test++)
1162  {
1163  printf("%02X ", pMsgBuf->Buf[Test]);
1164  }
1165  printf(" \r\n");
1166  #endif
1167 
1168  if (0 == AvailBytes)
1169  {
1170  // Read buffer is empty
1171  pReadBuf->OutPtr = 0;
1172  pReadBuf->InPtr = 0;
1173  pReadBuf->Status = READ_BUF_EMPTY;
1174  }
1175  }
1176  else
1177  {
1178  // Still some bytes needed to be received
1179  // So receive buffer is emptied
1180  memcpy(&(pMsgBuf->Buf[pMsgBuf->InPtr]), &(pReadBuf->Buf[pReadBuf->OutPtr]), AvailBytes);
1181 
1182  pMsgBuf->Status = MSG_BUF_BODY;
1183  pMsgBuf->RemMsgLen -= AvailBytes;
1184  pMsgBuf->InPtr += AvailBytes;
1185 
1186  pReadBuf->OutPtr = 0;
1187  pReadBuf->InPtr = 0;
1188  pReadBuf->Status = READ_BUF_EMPTY;
1189  }
1190  }
1191  }
1192  break;
1193 
1194  case MSG_BUF_FULL:
1195  {
1196  }
1197  break;
1198 
1199  default:
1200  {
1201  }
1202  break;
1203  }
1204 }
1205 
1206 
1207 void BtTurnOnSeq(void)
1208 {
1209  switch(BtInstance.OnOffSeqCnt)
1210  {
1211  case 0:
1212  {
1213  UBYTE Tmp;
1214  struct timespec TimerData;
1215 
1216  // Clear all channel buffers
1217  memset(&(BtInstance.BtCh), 0, sizeof(BtInstance.BtCh));
1218  for (Tmp = 0; Tmp < NO_OF_BT_CHS; Tmp++)
1219  {
1220  BtClearChBuf(Tmp);
1221  BtInstance.BtCh[Tmp].BtSocket.Socket = -1;
1222  }
1223  for (Tmp = 0; Tmp < MAX_DEV_TABLE_ENTRIES; Tmp++)
1224  {
1225  BtInstance.NonVol.DevList[Tmp].ChNo = NO_OF_BT_CHS;
1226  }
1227 
1228  BtInstance.Mode2WriteBuf.InPtr = 0;
1229  BtInstance.Mode2WriteBuf.OutPtr = 0;
1230 
1231  BtInstance.ScanState = SCAN_OFF;
1232  BtInstance.PageState = TRUE;
1233  BtInstance.ListenSocket.Socket = -1;
1234  BtInstance.NoOfFoundNames = 0;
1235  BtInstance.NoOfConnDevs = 0;
1236 
1237  BtInstance.HciSocket.Socket = hci_open_dev( 0 );
1238  ioctl(BtInstance.HciSocket.Socket, HCIDEVDOWN, 0);
1239  ioctl(BtInstance.HciSocket.Socket, HCIDEVUP, 0);
1240 
1241  clock_gettime(CLOCK_MONOTONIC,&TimerData);
1242  BtInstance.Delay = (ULONG)TimerData.tv_nsec;
1243 
1244  BtInstance.OnOffSeqCnt++ ;
1245  }
1246  break;
1247 
1248  case 1:
1249  {
1250  struct timespec TimerData;
1251  ULONG Time;
1252 
1253  cBtHandleHCI();
1254 
1255  clock_gettime(CLOCK_MONOTONIC,&TimerData);
1256  Time = (ULONG)TimerData.tv_nsec;
1257  if (400000000 < (Time - BtInstance.Delay))
1258  {
1259  // Wait min. 400mS
1260  // Events are setup here to be ready for coming hci_send_cmd
1261  BtSetupPinEvent();
1262  BtInstance.OnOffSeqCnt++;
1263  }
1264  }
1265  break;
1266 
1267  case 2:
1268  {
1269  if (MODE2 == BtInstance.NonVol.DecodeMode)
1270  {
1271  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_VENDOR_CMD, 0xFF26, 0x03, &SimplePairingEnable);
1272  }
1273  else
1274  {
1275  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_VENDOR_CMD, 0xFF26, 0x03, &SimplePairingDisable);
1276  }
1277  BtInstance.HciSocket.WaitForEvent = TRUE;
1278  BtInstance.OnOffSeqCnt++;
1279  }
1280  break;
1281 
1282  case 3:
1283  {
1284  cBtHandleHCI();
1285  if (FALSE == BtInstance.HciSocket.WaitForEvent)
1286  {
1287  if (MODE2 == BtInstance.NonVol.DecodeMode)
1288  {
1289  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_VENDOR_CMD, 0xFF26, 0x03, &ExtendedFeaturesEnable);
1290  }
1291  else
1292  {
1293  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_VENDOR_CMD, 0xFF26, 0x03, &ExtendedFeaturesDisable);
1294  }
1295  BtInstance.HciSocket.WaitForEvent = TRUE;
1296  BtInstance.OnOffSeqCnt++;
1297  }
1298  }
1299  break;
1300 
1301  case 4:
1302  {
1303  cBtHandleHCI();
1304  if (FALSE == BtInstance.HciSocket.WaitForEvent)
1305  {
1306  UBYTE Auth;
1307  if (MODE2 == BtInstance.NonVol.DecodeMode)
1308  {
1309  Auth = AUTH_DISABLED;
1310  }
1311  else
1312  {
1313  Auth = AUTH_ENABLED;
1314  }
1315 
1316  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &Auth);
1317  BtInstance.HciSocket.WaitForEvent = TRUE;
1318  BtInstance.OnOffSeqCnt++;
1319  }
1320  }
1321  break;
1322 
1323  case 5:
1324  {
1325  struct timespec TimerData;
1326 
1327  cBtHandleHCI();
1328  if (FALSE == BtInstance.HciSocket.WaitForEvent)
1329  {
1330  ioctl(BtInstance.HciSocket.Socket, HCIDEVDOWN, 0);
1331  ioctl(BtInstance.HciSocket.Socket, HCIDEVUP, 0);
1332 
1333  clock_gettime(CLOCK_MONOTONIC,&TimerData);
1334  BtInstance.Delay = (ULONG)TimerData.tv_nsec;
1335 
1336  BtInstance.OnOffSeqCnt++;
1337  }
1338  }
1339  break;
1340 
1341  case 6:
1342  {
1343  struct timespec TimerData;
1344  ULONG Time;
1345 
1346  cBtHandleHCI();
1347 
1348  clock_gettime(CLOCK_MONOTONIC,&TimerData);
1349  Time = (ULONG)TimerData.tv_nsec;
1350  if (400000000 < (Time - BtInstance.Delay))
1351  {
1352 
1353  // Update Name
1354  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
1355 
1356  BtInstance.HciSocket.WaitForEvent = TRUE;
1357  BtInstance.OnOffSeqCnt++;
1358  }
1359  }
1360  break;
1361 
1362  case 7:
1363  {
1364  cBtHandleHCI();
1365  if (FALSE == BtInstance.HciSocket.WaitForEvent)
1366  {
1367  change_local_name_cp cp;
1368 
1369  snprintf((char *)&(cp.name[0]), vmBRICKNAMESIZE, "%s", (char *)BtInstance.BtName);
1370  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, &cp);
1371  BtInstance.HciSocket.WaitForEvent = TRUE;
1372  BtInstance.OnOffSeqCnt++;
1373  }
1374  }
1375  break;
1376 
1377  case 8:
1378  {
1379  cBtHandleHCI();
1380  if (FALSE == BtInstance.HciSocket.WaitForEvent)
1381  {
1382  /* Setup Mode2 if it is enabled */
1383  if (MODE2 == BtInstance.NonVol.DecodeMode)
1384  {
1385  uint32_t svc_uuid_int[] = { 0, 0xDEFACADE, 0xAFDECADE, 0xFFCACADE };
1386  uint8_t rfcomm_channel = 1;
1387  const char *service_name = "Wireless EV3";
1388  const char *service_dsc = "MINDSTORMS EV3";
1389  const char *service_prov = "LEGO";
1390 
1391  int err = 0;
1392 
1393  uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid;//, svc_class_uuid;
1394  sdp_list_t *l2cap_list = 0,
1395  *rfcomm_list = 0,
1396  *root_list = 0,
1397  *proto_list = 0,
1398  *access_proto_list = 0,
1399  *svc_class_list = 0,
1400  *profile_list = 0;
1401  sdp_data_t *channel = 0; //, *psm = 0;
1402  sdp_profile_desc_t profile;
1403 
1404  UBYTE *pUUID;
1405  sdp_record_t *record = sdp_record_alloc();
1406 
1407  // set the general service ID
1408  sdp_uuid128_create( &svc_uuid, &svc_uuid_int );
1409 
1410  pUUID = &(svc_uuid.value.uuid128.data[0]);
1411 
1412  sdp_set_service_id( record, svc_uuid );
1413 
1414  pUUID = &(record->svclass.value.uuid128.data[0]);
1415 
1416  // set the service class
1417  svc_class_list = sdp_list_append(0, &svc_uuid);
1418  sdp_set_service_classes(record, svc_class_list);
1419 
1420  pUUID = &(record->svclass.value.uuid128.data[0]);
1421 
1422  // set the Bluetooth profile information
1423  sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
1424  profile.version = 0x0100;
1425  profile_list = sdp_list_append(0, &profile);
1426  sdp_set_profile_descs(record, profile_list);
1427 
1428  // make the service record publicly browsable
1429  sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
1430  root_list = sdp_list_append(0, &root_uuid);
1431  sdp_set_browse_groups( record, root_list );
1432 
1433  // set l2cap information
1434  sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
1435  l2cap_list = sdp_list_append( 0, &l2cap_uuid );
1436  proto_list = sdp_list_append( 0, l2cap_list );
1437 
1438  // register the RFCOMM channel for RFCOMM sockets
1439  sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
1440  channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
1441  rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
1442  sdp_list_append( rfcomm_list, channel );
1443  sdp_list_append( proto_list, rfcomm_list );
1444  access_proto_list = sdp_list_append( 0, proto_list );
1445  sdp_set_access_protos( record, access_proto_list );
1446 
1447  // set the name, provider, and description
1448  sdp_set_info_attr(record, service_name, service_prov, service_dsc);
1449 
1450  session = sdp_connect( BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY );
1451 
1452  pUUID = &(record->svclass.value.uuid128.data[0]);
1453 
1454  err = sdp_record_register(session, record, 0);
1455 
1456  // cleanup
1457  sdp_data_free( channel );
1458  sdp_list_free( l2cap_list, 0 );
1459  sdp_list_free( rfcomm_list, 0 );
1460  sdp_list_free( root_list, 0 );
1461  sdp_list_free( access_proto_list, 0 );
1462 
1463  sdp_list_free( proto_list, 0 );
1464  sdp_list_free( svc_class_list, 0 );
1465  sdp_list_free( profile_list, 0 );
1466 
1467  }
1468 
1469  BtInstance.OnOffSeqCnt++;
1470  }
1471  }
1472  break;
1473 
1474  case 9:
1475  {
1476  struct agent;
1477  char match_string[128], *adapter_id = NULL;
1478  struct sigaction sa;
1479 
1480  static const DBusObjectPathVTable agent_table =
1481  {
1482  .message_function = agent_message,
1483  };
1484  const char *capabilities = "DisplayYesNo";
1485 
1486  cBtHandleHCI();
1487  if (FALSE == BtInstance.HciSocket.WaitForEvent)
1488  {
1489  BtInstance.OnOffSeqCnt = 0;
1490  BtInstance.NonVol.On = TRUE;
1491  BtInstance.HciSocket.Busy &= ~HCI_ONOFF;
1493 
1494  conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1495  adapter_path = get_adapter_path(conn, adapter_id);
1496 
1497  if (!dbus_connection_register_object_path(conn, agent_path, &agent_table, NULL))
1498  {
1499  fprintf(stderr, "Can't register object path for agent\n");
1500  }
1501 
1502  if (register_agent(conn, adapter_path, agent_path, capabilities) < 0)
1503  {
1504  dbus_connection_unref(conn);
1505  exit(1);
1506  }
1507 
1508  if (!dbus_connection_add_filter(conn, agent_filter, NULL, NULL))
1509  fprintf(stderr, "Can't add signal filter");
1510 
1511  snprintf(match_string, sizeof(match_string),
1512  "interface=%s,member=NameOwnerChanged,arg0=%s",
1513  DBUS_INTERFACE_DBUS, "org.bluez");
1514 
1515  dbus_bus_add_match(conn, match_string, NULL);
1516 
1517  memset(&sa, 0, sizeof(sa));
1518  sa.sa_flags = SA_NOCLDSTOP;
1519  sa.sa_handler = sig_term;
1520  sigaction(SIGTERM, &sa, NULL);
1521  sigaction(SIGINT, &sa, NULL);
1522  }
1523  }
1524  break;
1525  }
1526 }
1527 
1528 
1529 void BtClose(void)
1530 {
1531  BtDisconnectAll();
1532 
1533  if (TRUE == BtInstance.NonVol.On)
1534  {
1535  // Unregister agent can only be done if already registered
1536  unregister_agent(conn, adapter_path, agent_path);
1537  }
1538 
1539  if (MODE2 == BtInstance.NonVol.DecodeMode)
1540  {
1541  if (0 != session)
1542  {
1543  sdp_close(session);
1544  session = 0;
1545  }
1546  }
1547 
1548  BtCloseBtSocket(&(BtInstance.ListenSocket.Socket));
1549 
1550  if (MIN_HANDLE <= BtInstance.HciSocket.Socket)
1551  {
1552  ioctl(BtInstance.HciSocket.Socket, HCIDEVDOWN, 0);
1553  hci_close_dev(BtInstance.HciSocket.Socket);
1554  BtInstance.HciSocket.Socket = -1;
1555  }
1556 
1557  I2cStop();
1558 }
1559 
1560 
1561 void BtTurnOffSeq(void)
1562 {
1563  BtClose();
1564 
1566  BtInstance.NonVol.On = FALSE;
1567  BtInstance.HciSocket.Busy = HCI_IDLE;
1568  BtInstance.OnOffSeqCnt = 0;
1569 }
1570 
1571 
1572 void BtUpdate(void)
1573 {
1574 
1575  switch(BtInstance.State)
1576  {
1577  case I_AM_IN_IDLE:
1578  {
1579  BTSOCKET *pBtSocket;
1580  UBYTE Index;
1581 
1582  cBtHandleHCI();
1583  dbus_connection_read_write_dispatch(conn, 0);
1584 
1585  pBtSocket = &(BtInstance.BtCh[0].BtSocket); // BtCh = 0 is the slave port
1586 
1587  // Check for incoming connection from known device
1588  BtInstance.ListenSocket.opt = sizeof(struct sockaddr_rc );
1589  pBtSocket->Socket = accept(BtInstance.ListenSocket.Socket, (struct sockaddr *)&(BtInstance.ListenSocket.rem_addr), &(BtInstance.ListenSocket.opt));
1590  if (0 <= pBtSocket->Socket)
1591  {
1592 
1593  #ifdef DEBUG
1594  char tmpbuf[50];
1595  #endif
1596 
1597  bacpy(&(pBtSocket->Addr),(bdaddr_t*)(&(BtInstance.ListenSocket.rem_addr.rc_bdaddr)));
1598 
1599  #ifdef DEBUG
1600  ba2str((const bdaddr_t*)(&(BtInstance.ListenSocket.rem_addr.rc_bdaddr)), tmpbuf);
1601  printf("Remote connection accepted, address: %s \r\n",tmpbuf);
1602  #endif
1603 
1604  if (OK == cBtFindDevAdr(&(pBtSocket->Addr), &Index))
1605  {
1606  cBtSetDevConnectedStatus(Index);
1607  }
1608  if (OK == cBtFindSearchAdr(&(BtInstance.NonVol.DevList[Index].Adr), &Index))
1609  {
1611  }
1612 
1614  BtInstance.BtCh[0].Status = CH_CONNECTED;
1615 
1616  if (MODE2 == BtInstance.NonVol.DecodeMode)
1617  {
1618  I2cStart();
1619  }
1620  }
1621  }
1622  break;
1623 
1624  case I_AM_SLAVE:
1625  {
1626  int BytesRead;
1627  READBUF *pReadBuf;
1628  BTSOCKET *pBtSocket;
1629 
1630  cBtHandleHCI();
1631 
1632  if (MODE1 == BtInstance.NonVol.DecodeMode)
1633  {
1634  pReadBuf = &(BtInstance.BtCh[0].ReadBuf); // BtCh = 0 is the slave port
1635  }
1636  else
1637  {
1638  pReadBuf = &(BtInstance.Mode2Buf); // dedicated buffer used for Mode2
1639  }
1640 
1641  pBtSocket = &(BtInstance.BtCh[0].BtSocket);
1642 
1643  if ((pBtSocket->Socket != -1))
1644  {
1645  /* Check if it is possible to read more byte from the BT stream */
1646  if (READ_BUF_EMPTY == pReadBuf->Status)
1647  {
1648  pBtSocket->Cmdtv.tv_sec = 0;
1649  pBtSocket->Cmdtv.tv_usec = 0;
1650  FD_ZERO(&(pBtSocket->Cmdfds));
1651  FD_SET(pBtSocket->Socket, &(pBtSocket->Cmdfds));
1652  if (select(pBtSocket->Socket + 1, &(pBtSocket->Cmdfds), NULL, NULL, &(pBtSocket->Cmdtv)))
1653  {
1654  BytesRead = read(pBtSocket->Socket, pReadBuf->Buf, sizeof(pReadBuf->Buf));
1655 
1656  if (0 <= BytesRead)
1657  {
1658  if (0 < BytesRead)
1659  {
1660 
1661  #ifdef DEBUG
1662  printf("\r\nData received on BT in Slave mode");
1663  #endif
1664 
1665  pReadBuf->OutPtr = 0;
1666  pReadBuf->InPtr = BytesRead;
1667  pReadBuf->Status = READ_BUF_FULL;
1668 
1669  #ifdef DEBUG
1670  for (Cnt = 0; Cnt < BytesRead; Cnt++)
1671  {
1672  printf("\r\n Rx byte nr %02d = %02X",Cnt,pReadBuf->Buf[Cnt]);
1673  }
1674  printf("\r\n");
1675  #endif
1676 
1677  DecodeBtStream((UBYTE) 0);
1678  }
1679  }
1680  else
1681  {
1682  // Socket closed at the other end -> close it
1683  BtCloseBtSocket(&(BtInstance.BtCh[0].BtSocket.Socket));
1684  }
1685  }
1686  }
1687  else
1688  {
1689  DecodeBtStream((UBYTE) 0);
1690  }
1691  }
1692  usleep(20);
1693  }
1694  break;
1695 
1696  case I_AM_MASTER:
1697  {
1698  // Can have up till 7 slaves - that is having up to 7 sockets to serve...
1699  // All packets go into the same buffer for the communication module and VM
1700  // and all packets needs to be wrapped with the channel number
1701  UBYTE Cnt;
1702  UBYTE Index;
1703  int BytesRead;
1704  READBUF *pReadBuf;
1705  BTSOCKET *pBtSocket;
1706  int SocketReturn;
1707 
1708  cBtHandleHCI();
1709  dbus_connection_read_write_dispatch(conn, 0);
1710 
1711  // Check all 7 channels
1712  for(Cnt = 1; Cnt < NO_OF_BT_CHS; Cnt++)
1713  {
1714 
1715  pReadBuf = &(BtInstance.BtCh[Cnt].ReadBuf);
1716  pBtSocket = &(BtInstance.BtCh[Cnt].BtSocket);
1717 
1718  if ((CH_FREE != BtInstance.BtCh[Cnt].Status) && (pBtSocket->Socket != -1))
1719  {
1720  if ((READ_BUF_EMPTY == pReadBuf->Status))
1721  {
1722  pBtSocket->Cmdtv.tv_sec = 0;
1723  pBtSocket->Cmdtv.tv_usec = 0;
1724  FD_ZERO(&(pBtSocket->Cmdfds));
1725  FD_SET(pBtSocket->Socket, &(pBtSocket->Cmdfds));
1726 
1727  if (CH_CONNECTING == BtInstance.BtCh[Cnt].Status)
1728  {
1729  // When writing becomes possible then socket is up running
1730  SocketReturn = select(pBtSocket->Socket + 1, NULL, &(pBtSocket->Cmdfds), NULL, &(pBtSocket->Cmdtv));
1731 
1732  if (0 < SocketReturn)
1733  {
1734  // This is acceptance from the slave
1735  if (OK == cBtFindDevChNo(Cnt, &Index))
1736  {
1737  cBtSetDevConnectedStatus(Index);
1738  }
1739  if (OK == cBtFindSearchAdr(&(BtInstance.NonVol.DevList[Index].Adr), &Index))
1740  {
1742  }
1743 
1744  BtInstance.HciSocket.Busy &= ~HCI_CONNECT;
1745  BtInstance.BtCh[Cnt].Status = CH_CONNECTED;
1746  }
1747  }
1748  else
1749  {
1750  if (0 < select(pBtSocket->Socket + 1, &(pBtSocket->Cmdfds), NULL, NULL, &(pBtSocket->Cmdtv)))
1751  {
1752  BytesRead = read(pBtSocket->Socket, pReadBuf->Buf, sizeof(pReadBuf->Buf));
1753  if (0 <= BytesRead)
1754  {
1755  if (0 < BytesRead)
1756  {
1757  pReadBuf->OutPtr = 0;
1758  pReadBuf->InPtr = BytesRead;
1759  pReadBuf->Status = READ_BUF_FULL;
1760 
1761  DecodeBtStream(Cnt);
1762  }
1763  }
1764  else
1765  {
1766  BtCloseBtSocket(&(pBtSocket->Socket));
1767  }
1768  }
1769  }
1770  }
1771  else
1772  {
1773  DecodeBtStream(Cnt);
1774  }
1775  }
1776  }
1777  usleep(20);
1778  }
1779  break;
1780 
1781  case I_AM_SCANNING:
1782  {
1783  cBtHandleHCI();
1784  }
1785  break;
1786 
1787  case TURN_ON:
1788  {
1789  BtTurnOnSeq();
1790  }
1791  break;
1792 
1793  case TURN_OFF:
1794  {
1795  BtTurnOffSeq();
1796  }
1797  break;
1798 
1799  case RESTART:
1800  {
1801  if (0 == BtInstance.RestartSeqCnt)
1802  {
1803  BtTurnOffSeq();
1804 
1805  // Check if power down is done
1806  if (0 == (HCI_ONOFF & BtInstance.HciSocket.Busy))
1807  {
1808  BtInstance.RestartSeqCnt++;
1809  BtInstance.HciSocket.Busy |= HCI_ONOFF;
1810 
1811  //Stay in this state - not an elegant way to do this!
1812  //But the BtTurnOffSeq sets state to OFF when done.
1813  BtInstance.State = RESTART;
1814  }
1815  }
1816  else
1817  {
1818  BtTurnOnSeq();
1819  }
1820  }
1821  break;
1822 
1823  case BLUETOOTH_OFF:
1824  {
1825  }
1826  break;
1827 
1828  default:
1829  {
1830  }
1831  break;
1832  }
1833  BtTxMsgs();
1834 }
1835 
1836 
1837 void create_paired_device_reply(DBusPendingCall *pending, void *user_data)
1838 {
1839  PAIREDDEVINFO *pPairedDevInfo;
1840  struct sockaddr_rc addr;
1841  int sock_flags, status;
1842 
1843 
1844  // Get the device info from the user data (device info is bluetooth addr and port number)
1845  pPairedDevInfo = (PAIREDDEVINFO*)user_data;
1846 
1847  BtInstance.BtCh[pPairedDevInfo->Port].BtSocket.Socket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1848 
1849  addr.rc_family = AF_BLUETOOTH;
1850  addr.rc_channel = 1;
1851 
1852  bacpy(&(addr.rc_bdaddr), &(pPairedDevInfo->Addr));
1853 
1854  sock_flags = fcntl(BtInstance.BtCh[pPairedDevInfo->Port].BtSocket.Socket, F_GETFL, 0);
1855  fcntl(BtInstance.BtCh[pPairedDevInfo->Port].BtSocket.Socket, F_SETFL, sock_flags | O_NONBLOCK);
1856 
1857  status = connect(BtInstance.BtCh[pPairedDevInfo->Port].BtSocket.Socket,(struct sockaddr *) &addr, sizeof(addr));
1858  BtClearChBuf(pPairedDevInfo->Port);
1859  BtInstance.BtCh[pPairedDevInfo->Port].Status = CH_CONNECTING;
1860 
1861  usleep(20);
1862 }
1863 
1864 
1865 UBYTE create_paired_device(DBusConnection *conn, const char *adapter_path,
1866  const char *agent_path,
1867  const char *capabilities,
1868  const char *device,
1869  UBYTE Port)
1870 {
1871  dbus_bool_t success;
1872  DBusMessage *msg;
1873  DBusPendingCall *pending;
1874 
1875  //Copy the device info to be used when paired reply is issued
1876  str2ba(device, &(PairedDevInfo.Addr));
1877  PairedDevInfo.Port = Port;
1878 
1879  msg = dbus_message_new_method_call("org.bluez", adapter_path, "org.bluez.Adapter", "CreatePairedDevice");
1880  if (!msg)
1881  {
1882  fprintf(stderr, "Can't allocate new method call\n");
1883  return(0);
1884  }
1885 
1886  dbus_message_append_args(msg, DBUS_TYPE_STRING, &device, DBUS_TYPE_OBJECT_PATH, &agent_path, DBUS_TYPE_STRING, &capabilities, DBUS_TYPE_INVALID);
1887 
1888  success = dbus_connection_send_with_reply(conn, msg, &pending, -1);
1889 
1890  if (pending)
1891  {
1892  dbus_pending_call_set_notify(pending, create_paired_device_reply, (void*)&PairedDevInfo, NULL);
1893  }
1894 
1895  dbus_message_unref(msg);
1896 
1897  if (!success)
1898  {
1899  fprintf(stderr, "Not enough memory for message send\n");
1900  return(0);
1901  }
1902 
1903  dbus_connection_flush(conn);
1904  usleep(20);
1905 
1906  return(1);
1907 }
1908 
1909 
1910 UBYTE BtConnectTo(UBYTE Port, bdaddr_t BtAddr)
1911 {
1912  const char *capabilities = "DisplayYesNo";
1913  char Addr[20];
1914  char Agent[128];
1915  UBYTE success;
1916  UBYTE RtnVal;
1917 
1918  snprintf(Agent, sizeof(Agent), "/org/bluez/agent_%d", getpid());
1919 
1920  ba2str((bdaddr_t *)(&(BtAddr)), Addr);
1921 
1922  success = create_paired_device(conn, adapter_path, Agent, capabilities, Addr, Port);
1923 
1924  if (!success)
1925  {
1926  RtnVal = FALSE;
1927  }
1928  else
1929  {
1930  RtnVal = TRUE;
1931  }
1932  return(RtnVal);
1933 }
1934 
1935 
1937 {
1938  UBYTE RtnVal = OK;
1939 
1940  if ((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy))
1941  {
1942  if (Mode2)
1943  {
1944  if (0 == BtInstance.NonVol.DecodeMode)
1945  {
1946  // If not already mode2 then set mode2
1947  BtInstance.NonVol.DecodeMode = MODE2;
1948 
1949  // Recycle on/off on BT to enable the changes
1950  if (BLUETOOTH_OFF != BtInstance.State)
1951  {
1952  BtInstance.HciSocket.Busy = HCI_RESTART;
1953  BtSetup(RESTART);
1954  }
1955  }
1956  else
1957  {
1958  BtInstance.HciSocket.Busy = HCI_IDLE;
1959  }
1960  }
1961  else
1962  {
1963  if (BtInstance.NonVol.DecodeMode)
1964  {
1965  // If in mode2 then set mode1
1966  BtInstance.NonVol.DecodeMode = MODE1;
1967 
1968  // Recycle on/off on BT to enable the changes
1969  if (BLUETOOTH_OFF != BtInstance.State)
1970  {
1971  BtInstance.HciSocket.Busy = HCI_RESTART;
1972  BtSetup(RESTART);
1973  }
1974  }
1975  else
1976  {
1977  BtInstance.HciSocket.Busy = HCI_IDLE;
1978  }
1979  }
1980  }
1981  else
1982  {
1983  RtnVal = FAIL;
1984  }
1985 
1986  return(RtnVal);
1987 }
1988 
1989 
1991 {
1992  UBYTE RtnVal = OK;
1993 
1994  *pMode2 = BtInstance.NonVol.DecodeMode;
1995 
1996  return(RtnVal);
1997 }
1998 
1999 
2001 {
2002  UBYTE RtnVal = OK;
2003 
2004  if ((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy))
2005  {
2006  if (On)
2007  {
2008  if(BLUETOOTH_OFF == BtInstance.State)
2009  {
2010  BtSetup(TURN_ON);
2011  BtInstance.HciSocket.Busy = HCI_ONOFF;
2012  }
2013  else
2014  {
2015  // Already ON
2016  BtInstance.HciSocket.Busy = HCI_IDLE;
2017  }
2018  }
2019  else
2020  {
2021  if (BLUETOOTH_OFF != BtInstance.State)
2022  {
2023  BtSetup(TURN_OFF);
2024  BtInstance.HciSocket.Busy = HCI_ONOFF;
2025  }
2026  else
2027  {
2028  // Already off
2029  BtInstance.HciSocket.Busy = HCI_IDLE;
2030  }
2031  }
2032  }
2033  else
2034  {
2035  RtnVal = FAIL;
2036  }
2037 
2038  return(RtnVal);
2039 }
2040 
2041 
2043 {
2044  UBYTE RtnVal = OK;
2045 
2046  *On = BtInstance.NonVol.On;
2047 
2048  return(RtnVal);
2049 }
2050 
2051 
2053 {
2054  UBYTE Visibility;
2055  UBYTE Status;
2056 
2057  Visibility = 0;
2058 
2059  if (Page)
2060  {
2061  Visibility |= SCAN_PAGE;
2062  }
2063 
2064  if (Visible)
2065  {
2066  Visibility |= SCAN_INQUIRY;
2067  }
2068 
2069  Status = hci_send_cmd(BtInstance.HciSocket.Socket, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &Visibility);
2070 
2071  return(Status);
2072 }
2073 
2074 
2075 /* Set visibility ON/OFF - which is the capability to respond to scanning */
2077 {
2078  UBYTE Status;
2079  UBYTE RtnVal;
2080 
2081  RtnVal = OK;
2082 
2083  if ((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy))
2084  {
2085  if (BLUETOOTH_OFF != BtInstance.State)
2086  {
2087  Status = BtIssueHciVisible(State, BtInstance.PageState);
2088  if (0 == Status)
2089  {
2090  BtInstance.HciSocket.Busy = HCI_VISIBLE;
2091  BtInstance.NonVol.Visible = State;
2092  }
2093  else
2094  {
2095  BtInstance.HciSocket.Busy = HCI_FAIL;
2096  }
2097  }
2098  else
2099  {
2100  BtInstance.HciSocket.Busy = HCI_IDLE;
2101  BtInstance.NonVol.Visible = State;
2102  }
2103  }
2104  else
2105  {
2106  RtnVal = FAIL;
2107  }
2108 
2109  return(RtnVal);
2110 }
2111 
2112 
2113 /* Get visibility */
2115 {
2116  return(BtInstance.NonVol.Visible);
2117 }
2118 
2119 
2120 UBYTE cBtFindDevName(UBYTE *pItem, UBYTE *pName, UBYTE StartIndex)
2121 {
2122  UBYTE RtnVal = FALSE;
2123  UBYTE Index;
2124 
2125  Index = StartIndex;
2126  if (0 == pName[0])
2127  {
2128  // If search name is 0 then it is wildcard *
2129  while((0 == BtInstance.NonVol.DevList[Index].Name[0]) && (Index < MAX_DEV_TABLE_ENTRIES))
2130  {
2131  Index++;
2132  }
2133  }
2134  else
2135  {
2136  while((0 != strcmp((char*)pName,(char*)BtInstance.NonVol.DevList[Index].Name)) && (Index < MAX_DEV_TABLE_ENTRIES))
2137  {
2138  Index++;
2139  }
2140  }
2141 
2142  if (Index < MAX_DEV_TABLE_ENTRIES)
2143  {
2144  RtnVal = TRUE;
2145  *pItem = Index;
2146  }
2147  return(RtnVal);
2148 }
2149 
2150 
2152 {
2153  UBYTE RtnVal;
2154 
2155  RtnVal = FAIL;
2156  if (Index < MAX_DEV_TABLE_ENTRIES)
2157  {
2158  memset(&(BtInstance.SearchList[Index].Adr.b[0]), 0, sizeof(bdaddr_t));
2159  BtInstance.SearchList[Index].Name[0] = 0;
2160  BtInstance.SearchList[Index].Connected = FALSE;
2161  BtInstance.SearchList[Index].Parred = FALSE;
2162  RtnVal = OK;
2163  }
2164  return(RtnVal);
2165 }
2166 
2167 
2169 {
2170  UBYTE RtnVal = FALSE;
2171  UBYTE Index;
2172 
2173  Index = 0;
2174  while((0 != strcmp((char*)pName,(char*)BtInstance.SearchList[Index].Name)) && (Index < MAX_DEV_TABLE_ENTRIES))
2175  {
2176  Index++;
2177  }
2178  if (Index < MAX_DEV_TABLE_ENTRIES)
2179  {
2180  RtnVal = TRUE;
2181  *pItem = Index;
2182  }
2183  return(RtnVal);
2184 }
2185 
2186 
2187 UBYTE Connect(bdaddr_t BdAddr, UBYTE PortNo)
2188 {
2189  UBYTE RtnVal;
2190  UBYTE Tmp;
2191 
2192  #ifdef DEBUG
2193  char Addr[20];
2194  #endif
2195 
2196  RtnVal = FALSE;
2197  if (I_AM_IN_IDLE == BtInstance.State)
2198  {
2199  // State allows to connect to other devices
2200  #ifdef DEBUG
2201  printf("Connecting from IDLE... \r\n");
2202  #endif
2203 
2205  if (TRUE == BtConnectTo(PortNo, BdAddr))
2206  {
2207  RtnVal = TRUE;
2208  }
2209  else
2210  {
2211  //Connection attempt failed return to idle
2213  RtnVal = FALSE;
2214  }
2215  }
2216  else
2217  {
2218  if (I_AM_MASTER == BtInstance.State)
2219  {
2220  // Can be the master of up to 7 units
2221  #ifdef DEBUG
2222  ba2str(&(BtInstance.NonVol.DevList[Item].Adr), Addr);
2223  printf("Connecting from MASTER PortIndex = %d, Addr = %s \r\n",PortIndex,Addr);
2224  #endif
2225 
2226  if (FALSE == BtConnectTo(PortNo, BdAddr))
2227  {
2228  RtnVal = TRUE;
2229  }
2230  else
2231  {
2232  RtnVal = FALSE;
2233  }
2234  }
2235  else
2236  {
2237  if (I_AM_SLAVE == BtInstance.State)
2238  {
2239  // An outgoing connection will always disconnect Ch 0
2240  // if already connected
2241  for(Tmp = 0; Tmp < MAX_DEV_TABLE_ENTRIES; Tmp++)
2242  {
2243  if ((TRUE == BtInstance.NonVol.DevList[Tmp].Connected) && (0 == BtInstance.NonVol.DevList[Tmp].ChNo))
2244  {
2245  cBtDisconnect((UBYTE *)BtInstance.NonVol.DevList[Tmp].Name);
2246  Tmp = MAX_DEV_TABLE_ENTRIES;
2247  }
2248  }
2250 
2251  if (TRUE == BtConnectTo(PortNo, BdAddr))
2252  {
2253  RtnVal = TRUE;
2254  }
2255  else
2256  {
2257  //Incoming connection has been closed and connection attempt failed -> return to idle
2259  RtnVal = FALSE;
2260  }
2261  }
2262  else
2263  {
2264  // Mode does not allow connecting
2265  #ifdef DEBUG
2266  printf("Wrong Mode... = %d \r\n", (int)BtInstance.State);
2267  #endif
2268  }
2269  }
2270  }
2271  return(RtnVal);
2272 }
2273 
2274 
2275 /* This is the entry level to connecting */
2277 {
2278  UBYTE RtnVal;
2279  UBYTE Index;
2280  UBYTE PortIndex;
2281  bdaddr_t *pBdAddr;
2282  UBYTE AllReadyConn;
2283 
2284  RtnVal = OK;
2285  AllReadyConn = FALSE;
2286  if (((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy)) && (BLUETOOTH_OFF != BtInstance.State))
2287  {
2288  if (MODE1 == BtInstance.NonVol.DecodeMode)
2289  {
2290  //First check if already connected (can only be done if NOT using UI)
2291  if (TRUE == cBtFindDevName(&Index, pDevName, 0))
2292  {
2293  if (TRUE == BtInstance.NonVol.DevList[Index].Connected)
2294  {
2295  AllReadyConn = TRUE;
2296  BtInstance.HciSocket.Busy = HCI_IDLE;
2297  }
2298  }
2299 
2300  if (FALSE == AllReadyConn)
2301  {
2302  // Find free port to use for connection
2303  PortIndex = BT_HOST_CH0;
2304  while((PortIndex < NO_OF_BT_CHS) && (CH_FREE != BtInstance.BtCh[PortIndex].Status))
2305  {
2306  PortIndex++;
2307  }
2308 
2309  if (NO_OF_BT_CHS > PortIndex)
2310  {
2311  // Set Busy flag to signal upwards
2312  BtInstance.HciSocket.Busy = HCI_CONNECT;
2313  BtInstance.OutGoing.ChNo = PortIndex;
2314 
2315  #ifdef DEBUG
2316  printf("\r\n ..... c_bt_connect....Name = %s\r\n",pDevName);
2317  #endif
2318 
2319  // First look in the known list
2320  if (TRUE == cBtFindDevName(&Index, pDevName, 0))
2321  {
2322  #ifdef DEBUG
2323  printf("\r\nFound in dev table: index = %d, name = %s, Port no = %d\r\n", Index, pDevName, PortIndex);
2324  #endif
2325 
2326  pBdAddr = &(BtInstance.NonVol.DevList[Index].Adr);
2327  }
2328  else
2329  {
2330  // Then look in the search list
2331  if (TRUE == cBtFindSearchName(&Index, pDevName))
2332  {
2333  #ifdef DEBUG
2334  printf("\r\n ..... Found in search table index = %d.... name = %s\r\n", Index, pDevName);
2335  #endif
2336 
2337  pBdAddr = &(BtInstance.SearchList[Index].Adr);
2338  }
2339  else
2340  {
2341  RtnVal = FAIL;
2342  BtInstance.HciSocket.Busy = HCI_FAIL;
2343  }
2344  }
2345 
2346  if (0 == (HCI_FAIL & BtInstance.HciSocket.Busy))
2347  {
2348  // All above went OK -> Connect
2349  // Put name in incoming so it can be viewed in pin code pop up screen
2350  snprintf((char*)&(BtInstance.Incoming.Name[0]), vmBRICKNAMESIZE, "%s", (char*)pDevName);
2351  if (FALSE == Connect(*pBdAddr, PortIndex))
2352  {
2353  RtnVal = FAIL;
2354  BtInstance.HciSocket.Busy = HCI_FAIL;
2355  }
2356  }
2357  }
2358  else
2359  {
2360  // No more free ports
2361  RtnVal = FAIL;
2362  BtInstance.HciSocket.Busy = HCI_FAIL;
2363  }
2364  }
2365  }
2366  else
2367  {
2368  RtnVal = FAIL;
2369  BtInstance.HciSocket.Busy = HCI_FAIL;
2370  }
2371  }
2372  else
2373  {
2374  RtnVal = FAIL;
2375  BtInstance.HciSocket.Busy = HCI_FAIL;
2376  }
2377  return(RtnVal);
2378 }
2379 
2380 
2382 {
2383  UBYTE RtnVal;
2384 
2385  RtnVal = FALSE;
2386  if(TRUE == BtInstance.NonVol.DevList[Index].Connected)
2387  {
2388  BtInstance.HciSocket.Busy = HCI_DISCONNECT;
2389  BtCloseBtSocket(&(BtInstance.BtCh[BtInstance.NonVol.DevList[Index].ChNo].BtSocket.Socket));
2390  RtnVal = TRUE;
2391  }
2392  return(RtnVal);
2393 }
2394 
2395 
2397 {
2398  UBYTE RtnVal;
2399  UBYTE TmpCnt;
2400 
2401  RtnVal = FALSE;
2402  for(TmpCnt = 0; TmpCnt < MAX_DEV_TABLE_ENTRIES; TmpCnt++)
2403  {
2404  if ((TRUE == BtInstance.NonVol.DevList[TmpCnt].Connected) && (ChNo == BtInstance.NonVol.DevList[TmpCnt].ChNo))
2405  {
2406  cBtDiscDevIndex(TmpCnt);
2407  TmpCnt = MAX_DEV_TABLE_ENTRIES;
2408  RtnVal = TRUE;
2409  }
2410  }
2411  return(RtnVal);
2412 }
2413 
2414 
2416 {
2417  UBYTE Index;
2418  UBYTE RtnVal;
2419  UBYTE TmpCnt;
2420 
2421  // Disconnect by name - find first index with the name which is connected
2422  if (((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy)) && (BLUETOOTH_OFF != BtInstance.State))
2423  {
2424  for(TmpCnt = 0; TmpCnt < MAX_DEV_TABLE_ENTRIES; TmpCnt++)
2425  {
2426  BtInstance.HciSocket.Busy = HCI_IDLE;
2427  if (TRUE == cBtFindDevName(&Index, pName, TmpCnt))
2428  {
2429  if (cBtDiscDevIndex(Index))
2430  {
2431  TmpCnt = MAX_DEV_TABLE_ENTRIES;
2432  }
2433  else
2434  {
2435  // The device was found but not connected -
2436  // Keep looking for a connected device
2437  TmpCnt = Index;
2438  }
2439  }
2440  else
2441  {
2442  TmpCnt = MAX_DEV_TABLE_ENTRIES;
2443  }
2444  }
2445 
2446  #ifdef DEBUG
2447  printf("\r\nDisconnecting Index = %d, Socketno = %d, Name = %s",Index,BtInstance.BtCh[BtInstance.NonVol.DevList[Index].ChNo].BtSocket.Socket,pName);
2448  #endif
2449 
2450  RtnVal = OK;
2451  }
2452  else
2453  {
2454  BtInstance.HciSocket.Busy = HCI_FAIL;
2455  RtnVal = FAIL;
2456  }
2457  return(RtnVal);
2458 }
2459 
2460 
2461 void BtTxMsgs(void)
2462 {
2463  UBYTE Cnt;
2464  UWORD ByteCnt;
2465  SWORD NoWritten;
2466  WRITEBUF *pWriteBuf;
2467  BTSOCKET *pBtSocket;
2468  int SocketReturn;
2469 
2470  for (Cnt = 0; Cnt < NO_OF_BT_CHS; Cnt++)
2471  {
2472  pWriteBuf = &(BtInstance.BtCh[Cnt].WriteBuf);
2473  pBtSocket = &(BtInstance.BtCh[Cnt].BtSocket);
2474 
2475  ByteCnt = pWriteBuf->InPtr - pWriteBuf->OutPtr;
2476 
2477  if(ByteCnt)
2478  {
2479  if (-1 != pBtSocket->Socket)
2480  {
2481 
2482  pBtSocket->Cmdtv.tv_sec = 0;
2483  pBtSocket->Cmdtv.tv_usec = 0;
2484  FD_ZERO(&(pBtSocket->Cmdfds));
2485  FD_SET(pBtSocket->Socket, &(pBtSocket->Cmdfds));
2486 
2487  SocketReturn = select(pBtSocket->Socket + 1, NULL, &(pBtSocket->Cmdfds), NULL, &(pBtSocket->Cmdtv));
2488 
2489  if (0 < SocketReturn)
2490  {
2491  // Still bytes to transmit on the requested channel
2492  NoWritten = send(pBtSocket->Socket, &(pWriteBuf->Buf[pWriteBuf->OutPtr]), ByteCnt, (int)0);
2493 
2494  if (0 < NoWritten)
2495  {
2496  pWriteBuf->OutPtr += NoWritten;
2497 
2498  #ifdef DEBUG
2499  printf("\r\n.... transmitted to socket = %d on chno = %d, Bytes to send %d, Bytes written = %d \r\n",pBtSocket->Socket, Cnt, ByteCnt, NoWritten);
2500  printf("\r\n errno = %d\r\n", errno);
2501  #endif
2502 
2503  if (pWriteBuf->OutPtr == pWriteBuf->InPtr)
2504  {
2505  // All bytes has been written - clear the buffer
2506  pWriteBuf->InPtr = 0;
2507  pWriteBuf->OutPtr = 0;
2508  }
2509  }
2510  }
2511  }
2512  else
2513  {
2514  // Socket is closed (illegal handle) -> flush buffer
2515  pWriteBuf->InPtr = 0;
2516  pWriteBuf->OutPtr = 0;
2517  }
2518  }
2519  }
2520 }
2521 
2522 
2524 {
2525  UBYTE RtnVal;
2526 
2527  RtnVal = 1;
2528  if(0 != BtInstance.BtCh[0].WriteBuf.InPtr)
2529  {
2530  RtnVal = 0;
2531  }
2532  return(RtnVal);
2533 }
2534 
2535 
2537 {
2538  if(0 == BtInstance.BtCh[0].WriteBuf.InPtr)
2539  {
2540  memcpy(BtInstance.BtCh[0].WriteBuf.Buf, pBuf, Size);
2541  BtInstance.BtCh[0].WriteBuf.InPtr = Size;
2542  }
2543  return(Size);
2544 }
2545 
2546 
2548 {
2549  if (MODE2 == BtInstance.NonVol.DecodeMode)
2550  {
2551  if(0 == BtInstance.Mode2WriteBuf.InPtr)
2552  {
2553  memcpy(BtInstance.Mode2WriteBuf.Buf, pBuf, Size);
2554  BtInstance.Mode2WriteBuf.InPtr = Size;
2555  }
2556  else
2557  {
2558  Size = 0;
2559  }
2560  }
2561  else
2562  {
2563  if(0 == BtInstance.BtCh[0].WriteBuf.InPtr)
2564  {
2565  memcpy(BtInstance.BtCh[0].WriteBuf.Buf, pBuf, Size);
2566  BtInstance.BtCh[0].WriteBuf.InPtr = Size;
2567  }
2568  else
2569  {
2570  Size = 0;
2571  }
2572  }
2573  return(Size);
2574 }
2575 
2576 
2578 {
2579  if(0 == BtInstance.BtCh[1].WriteBuf.InPtr)
2580  {
2581  memcpy(BtInstance.BtCh[1].WriteBuf.Buf, pBuf, Size);
2582  BtInstance.BtCh[1].WriteBuf.InPtr = Size;
2583  }
2584  else
2585  {
2586  Size = 0;
2587  }
2588  return(Size);
2589 }
2590 
2591 
2593 {
2594  if(0 == BtInstance.BtCh[2].WriteBuf.InPtr)
2595  {
2596  memcpy(BtInstance.BtCh[2].WriteBuf.Buf, pBuf, Size);
2597  BtInstance.BtCh[2].WriteBuf.InPtr = Size;
2598  }
2599  else
2600  {
2601  Size = 0;
2602  }
2603  return(Size);
2604 }
2605 
2606 
2608 {
2609  if(0 == BtInstance.BtCh[3].WriteBuf.InPtr)
2610  {
2611  memcpy(BtInstance.BtCh[3].WriteBuf.Buf, pBuf, Size);
2612  BtInstance.BtCh[3].WriteBuf.InPtr = Size;
2613  }
2614  else
2615  {
2616  Size = 0;
2617  }
2618  return(Size);
2619 }
2620 
2621 
2623 {
2624  if(0 == BtInstance.BtCh[4].WriteBuf.InPtr)
2625  {
2626  memcpy(BtInstance.BtCh[4].WriteBuf.Buf, pBuf, Size);
2627  BtInstance.BtCh[4].WriteBuf.InPtr = Size;
2628  }
2629  else
2630  {
2631  Size = 0;
2632  }
2633  return(Size);
2634 }
2635 
2636 
2638 {
2639  if(0 == BtInstance.BtCh[5].WriteBuf.InPtr)
2640  {
2641  memcpy(BtInstance.BtCh[5].WriteBuf.Buf, pBuf, Size);
2642  BtInstance.BtCh[5].WriteBuf.InPtr = Size;
2643  }
2644  else
2645  {
2646  Size = 0;
2647  }
2648  return(Size);
2649 }
2650 
2651 
2653 {
2654  if(0 == BtInstance.BtCh[6].WriteBuf.InPtr)
2655  {
2656  memcpy(BtInstance.BtCh[6].WriteBuf.Buf, pBuf, Size);
2657  BtInstance.BtCh[6].WriteBuf.InPtr = Size;
2658  }
2659  else
2660  {
2661  Size = 0;
2662  }
2663  return(Size);
2664 }
2665 
2666 
2668 {
2669  if(0 == BtInstance.BtCh[7].WriteBuf.InPtr)
2670  {
2671  memcpy(BtInstance.BtCh[7].WriteBuf.Buf, pBuf, Size);
2672  BtInstance.BtCh[7].WriteBuf.InPtr = Size;
2673  }
2674  else
2675  {
2676  Size = 0;
2677  }
2678  return(Size);
2679 }
2680 
2681 
2682 UBYTE cBtFindSearchAdr(bdaddr_t *pAdr, UBYTE *pIndex)
2683 {
2684  UBYTE Cnt;
2685  UBYTE RtnVal;
2686 
2687  RtnVal = FAIL;
2688  for (Cnt = 0; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FAIL == RtnVal)); Cnt++)
2689  {
2690  if (0 == bacmp(pAdr, &(BtInstance.SearchList[Cnt].Adr)))
2691  {
2692  *pIndex = Cnt;
2693  RtnVal = OK;
2694  }
2695  }
2696  return(RtnVal);
2697 }
2698 
2699 
2700 UBYTE cBtFindDevAdr(bdaddr_t *pAdr, UBYTE *pIndex)
2701 {
2702  UBYTE Cnt;
2703  UBYTE RtnVal;
2704 
2705  RtnVal = FAIL;
2706  for (Cnt = 0; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FAIL == RtnVal)); Cnt++)
2707  {
2708  if ((DEV_EMPTY != BtInstance.NonVol.DevList[Cnt].Status) &&
2709  (0 == bacmp(pAdr, &(BtInstance.NonVol.DevList[Cnt].Adr))))
2710  {
2711  *pIndex = Cnt;
2712  RtnVal = OK;
2713  }
2714  }
2715  return(RtnVal);
2716 }
2717 
2718 
2720 {
2721  UBYTE Cnt;
2722  UBYTE RtnVal;
2723 
2724  RtnVal = FAIL;
2725  for (Cnt = 0; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FAIL == RtnVal)); Cnt++)
2726  {
2727  if ((DEV_EMPTY != BtInstance.NonVol.DevList[Cnt].Status) &&
2728  (ConnHandle == BtInstance.NonVol.DevList[Cnt].ConnHandle) &&
2729  (TRUE == BtInstance.NonVol.DevList[Cnt].Connected))
2730  {
2731  *pIndex = Cnt;
2732  RtnVal = OK;
2733  }
2734  }
2735  return(RtnVal);
2736 }
2737 
2738 
2740 {
2741  UBYTE Cnt;
2742  UBYTE RtnVal;
2743 
2744  RtnVal = FAIL;
2745  for (Cnt = 0; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FAIL == RtnVal)); Cnt++)
2746  {
2747  if ((DEV_EMPTY != BtInstance.NonVol.DevList[Cnt].Status) &&
2748  (ChNo == BtInstance.NonVol.DevList[Cnt].ChNo) &&
2749  (CH_FREE != BtInstance.BtCh[ChNo].Status))
2750  {
2751  *pIndex = Cnt;
2752  RtnVal = OK;
2753  }
2754  }
2755  return(RtnVal);
2756 }
2757 
2758 
2759 UBYTE cBtInsertInDeviceList(bdaddr_t *pBtAdr, UBYTE *pIndex)
2760 {
2761  UBYTE Cnt;
2762  UBYTE Exit;
2763  UBYTE RtnVal;
2764 
2765  RtnVal = OK;
2766 
2767  //Check if already present
2768  Exit = FALSE;
2769  for (Cnt = 0; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FALSE == Exit)); Cnt++)
2770  {
2771  if (DEV_EMPTY != BtInstance.NonVol.DevList[Cnt].Status)
2772  {
2773  if (0 == bacmp(&(BtInstance.NonVol.DevList[Cnt].Adr), pBtAdr))
2774  {
2775  *pIndex = Cnt;
2776  Exit = TRUE;
2777  }
2778  }
2779  }
2780 
2781  if (FALSE == Exit)
2782  {
2783  // Device not already present -> Create one
2784  for (Cnt = 0; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FALSE == Exit)); Cnt++)
2785  {
2786  if (DEV_EMPTY == BtInstance.NonVol.DevList[Cnt].Status)
2787  {
2788  BtInstance.NonVol.DevListEntries++;
2789  BtInstance.NonVol.DevList[Cnt].Name[0] = 0;
2790  BtInstance.NonVol.DevList[Cnt].Status = DEV_KNOWN;
2791  bacpy(&(BtInstance.NonVol.DevList[Cnt].Adr), pBtAdr);
2792  *pIndex = Cnt;
2793  Exit = TRUE;
2794  }
2795  }
2796  }
2797 
2798  if (FALSE == Exit)
2799  {
2800  RtnVal = FAIL;
2801  }
2802  return(RtnVal);
2803 }
2804 
2805 
2807 {
2808  BtInstance.NonVol.DevList[Index].Connected = TRUE;
2809  BtInstance.NoOfConnDevs++;
2810 }
2811 
2812 
2814 {
2815  BtInstance.NonVol.DevList[Index].Connected = FALSE;
2816 
2817  // BtInstance.NoOfConnDevs is updated in BtCloseCh function
2818  BtCloseCh(BtInstance.NonVol.DevList[Index].ChNo);
2819  BtInstance.NonVol.DevList[Index].ChNo = NO_OF_BT_CHS;
2820 }
2821 
2822 
2824 {
2825  BtInstance.SearchList[Index].Connected = TRUE;
2826  BtInstance.SearchList[Index].Parred = TRUE;
2827 }
2828 
2829 
2831 {
2832  BtInstance.SearchList[Index].Connected = FALSE;
2833 }
2834 
2835 
2836 void cBtInsertDevConnHandle(UBYTE Index, UWORD ConnHandle)
2837 {
2838  BtInstance.NonVol.DevList[Index].ConnHandle = ConnHandle;
2839 }
2840 
2841 
2908 {
2909  UWORD RtnVal;
2910  int len;
2911  int results;
2912  unsigned char buf[HCI_MAX_EVENT_SIZE];
2913  unsigned char *ptr;
2914  hci_event_hdr *hdr;
2915 
2916  RtnVal = TRUE;
2917 
2918  // Poll the HCI socket for pin key request
2919  BtInstance.HciSocket.p.revents = 0;
2920 
2921  if (poll(&(BtInstance.HciSocket.p), 1, 0) > 0)
2922  {
2923  len = read(BtInstance.HciSocket.Socket, buf, sizeof(buf));
2924 
2925  if (len > 0)
2926  {
2927 
2928  hdr = (void *) (buf + 1);
2929  ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
2930  results = ptr[0];
2931 
2932  switch (hdr->evt)
2933  {
2934 
2935  case EVT_PIN_CODE_REQ:
2936  {
2937 
2938  if (0 == bacmp(&(BtInstance.TrustedDev.Adr), &((evt_pin_code_req*)ptr)->bdaddr))
2939  {
2940  // If pincode request is from a trusted dev. then signal to the DBUS handle
2941  // that it is trusted
2942  BtInstance.TrustedDev.Status = TRUE;
2943  bacpy(&(BtInstance.TrustedDev.Adr), BDADDR_ANY); //Address can only be used once
2944  }
2945  }
2946  break;
2947 
2948  case EVT_CONN_REQUEST:
2949  {
2950  if (I_AM_IN_IDLE == BtInstance.State)
2951  {
2952  // Connection from the outside - coming from the listen socket
2953  // Need to add it to the dev list and search list if possible
2954  remote_name_req_cp cp;
2955 
2956  #ifdef DEBUG
2957  printf("EVT_CONN_REQUEST from outside this is slave..... \r\n");
2958  #endif
2959 
2960  // Save information regarding incoming connection
2961  bacpy(&(BtInstance.Incoming.Adr), &((evt_conn_request*)ptr)->bdaddr);
2962  memcpy(&(BtInstance.Incoming.DevClass[0]), &(((evt_conn_request*)ptr)->dev_class[0]), 3);
2963  BtInstance.Incoming.Name[0] = 0; //Clear name, it is not available yet
2964 
2965  // Issue name request because it is coming from the outside
2966  memset(&cp, 0, sizeof(cp));
2967  bacpy(&cp.bdaddr, &((evt_conn_request*)ptr)->bdaddr);
2968  cp.pscan_rep_mode = 0x02;
2969  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, REMOTE_NAME_REQ_CP_SIZE, &cp);
2970  }
2971  }
2972  break;
2973 
2974  case EVT_CONN_COMPLETE:
2975  {
2976  UBYTE DevIndex;
2977  UBYTE SearchIndex;
2978 
2979  if (0 != ((evt_conn_complete*)ptr)->status)
2980  {
2981  if (I_AM_MASTER == BtInstance.State)
2982  {
2983  if (OK == cBtFindDevAdr(&((evt_conn_complete*)ptr)->bdaddr, &DevIndex))
2984  {
2985  //Need to insert the correct channel number to close it
2986  BtInstance.NonVol.DevList[DevIndex].ChNo = BtInstance.OutGoing.ChNo;
2987  cBtCloseDevConnection(DevIndex);
2988  }
2989  }
2990 
2991  #ifdef DEBUG
2992  printf("EVT_CONN_COMPLETE - FAIL !!!!! Status = %d \r\n",((evt_conn_complete*)ptr)->status);
2993  #endif
2994  BtInstance.HciSocket.Busy &= ~HCI_CONNECT;
2995  }
2996  else
2997  {
2998  // Now connected to one device -> Disable incoming connect requests
2999  // This command repeated for each connected device in master mode
3000  BtInstance.PageState = 0;
3001  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
3002  BtInstance.HciSocket.Busy |= HCI_VISIBLE;
3003 
3004  if (FAIL != cBtFindDevAdr(&((evt_conn_complete*)ptr)->bdaddr, &DevIndex))
3005  {
3006  cBtInsertDevConnHandle(DevIndex, ((evt_conn_complete*)ptr)->handle);
3007 
3008  if (I_AM_MASTER == BtInstance.State)
3009  {
3010  BtInstance.NonVol.DevList[DevIndex].ChNo = BtInstance.OutGoing.ChNo;
3011 
3012  if (OK == cBtFindSearchAdr(&((evt_conn_complete*)ptr)->bdaddr, &SearchIndex))
3013  {
3014  // Insert COD from search list
3015  memcpy(&(BtInstance.NonVol.DevList[DevIndex].DevClass[0]),&(BtInstance.SearchList[SearchIndex].DevClass[0]),3);
3016  }
3017  }
3018  else
3019  {
3020  // Connections from the outside (I am a slave) always uses ch 0
3021  BtInstance.NonVol.DevList[DevIndex].ChNo = 0;
3022  memcpy(&(BtInstance.NonVol.DevList[DevIndex].DevClass[0]),&(BtInstance.Incoming.DevClass[0]),3);
3023  }
3024  }
3025 
3026  BtInstance.Incoming.ConnHandle = ((evt_conn_complete*)ptr)->handle;
3027  }
3028  }
3029  break;
3030 
3031  case EVT_INQUIRY_RESULT_WITH_RSSI:
3032  {
3033  int i;
3034  inquiry_info_with_rssi *info_rssi;
3035  UBYTE DevStatus;
3036  UBYTE Tmp;
3037 
3038  for (i = 0; i < results; i++)
3039  {
3040  info_rssi = (void *)ptr + (sizeof(*info_rssi) * i) + 1;
3041 
3042  bacpy(&(BtInstance.SearchList[BtInstance.SearchIndex].Adr), &(info_rssi->bdaddr));
3043  memcpy(&(BtInstance.SearchList[BtInstance.SearchIndex].DevClass[0]), &(info_rssi->dev_class[0]), 3);
3044 
3045  DevStatus = FALSE;
3046  for (Tmp = 0; ((Tmp < MAX_DEV_TABLE_ENTRIES) && (DevStatus == FALSE)); Tmp++)
3047  {
3048 
3049  if (DEV_EMPTY != BtInstance.NonVol.DevList[Tmp].Status)
3050  {
3051 
3052  if (0 == bacmp(&(BtInstance.NonVol.DevList[Tmp].Adr), &(info_rssi->bdaddr)))
3053  {
3054  // The device was in the dev list -> it is paired -> Check for connected...
3055  BtInstance.SearchList[BtInstance.SearchIndex].Parred = TRUE;
3056  BtInstance.SearchList[BtInstance.SearchIndex].Connected = BtInstance.NonVol.DevList[Tmp].Connected;
3057 
3058  // Update Class of Device
3059  memcpy(&(BtInstance.NonVol.DevList[Tmp].DevClass[0]), &(info_rssi->dev_class[0]), 3);
3060 
3061  DevStatus = TRUE;
3062  }
3063  }
3064  }
3065 
3066  if (FALSE == DevStatus)
3067  {
3068  BtInstance.SearchList[BtInstance.SearchIndex].Parred = FALSE;
3069  BtInstance.SearchList[BtInstance.SearchIndex].Connected = FALSE;
3070  }
3071 
3072  (BtInstance.SearchIndex)++;
3073  }
3074  }
3075  break;
3076 
3077  case EVT_INQUIRY_COMPLETE:
3078  {
3079  BtInstance.NoOfFoundDev = BtInstance.SearchIndex;
3080  BtInstance.SearchIndex = 0;
3081 
3082  if (0 == BtInstance.NoOfFoundDev)
3083  {
3084  if (SCAN_INQ_STATE == BtInstance.ScanState)
3085  {
3086 
3087  // No devices found
3088  #ifdef DEBUG
3089  printf("inquiry done.... exiting \r\n");
3090  #endif
3091 
3092  BtSetup(BtInstance.OldState); // Return to previous state
3093  BtInstance.HciSocket.Busy &= ~HCI_SCAN;
3094  BtInstance.ScanState = SCAN_OFF;
3095  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
3096  }
3097  }
3098  else
3099  {
3100  if (SCAN_INQ_STATE == BtInstance.ScanState)
3101  {
3102  BtInstance.ScanState = SCAN_NAME_STATE;
3103  BtRequestName();
3104  }
3105  else
3106  {
3107 
3108  // Scan has been terminated
3109  BtSetup(BtInstance.OldState); // Return to previous state
3110  BtInstance.ScanState = SCAN_OFF;
3111  BtInstance.HciSocket.Busy &= ~HCI_SCAN;
3112  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
3113  }
3114  }
3115  }
3116  break;
3117 
3118  case EVT_REMOTE_NAME_REQ_COMPLETE:
3119  {
3120  // Remote name complete will occur during connect!!
3121  evt_remote_name_req_complete *rn;
3122  UBYTE Cnt;
3123  UBYTE Exit;
3124 
3125  #ifdef DEBUG
3126  printf("EVT_REMOTE_NAME_REQ_COMPLETE\r\n");
3127  char TmpAddr[16];
3128  #endif
3129 
3130  rn = (void *)ptr;
3131  if (I_AM_SCANNING == BtInstance.State)
3132  {
3133  if(rn->status)
3134  {
3135  strcpy(BtInstance.SearchList[BtInstance.SearchIndex].Name, "????");
3136  }
3137  else
3138  {
3139  strcpy(BtInstance.SearchList[BtInstance.SearchIndex].Name, (char*)rn->name);
3140 
3141  // Update favourite list with the name received
3142  for (Cnt = 0, Exit = FALSE; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FALSE == Exit)); Cnt++)
3143  {
3144  if (DEV_EMPTY != BtInstance.NonVol.DevList[Cnt].Status)
3145  {
3146  if (0 == bacmp(&(BtInstance.NonVol.DevList[Cnt].Adr), (bdaddr_t*)&(rn->bdaddr)))
3147  {
3148 
3149  #ifdef DEBUG
3150  printf("\r\nUpdated name in favourite list \r\n");
3151  #endif
3152 
3153  strcpy(BtInstance.NonVol.DevList[Cnt].Name, (char*)rn->name);
3154 
3155  Exit = TRUE;
3156  }
3157  }
3158  }
3159  }
3160 
3161  #ifdef DEBUG
3162  ba2str((const bdaddr_t *)(&BtInstance.SearchList[BtInstance.SearchIndex].Adr), TmpAddr);
3163  printf("Dev Table[%d]: Addr = %s, Name = %s \r\n", BtInstance.SearchIndex, TmpAddr, BtInstance.SearchList[BtInstance.SearchIndex].Name);
3164  #endif
3165 
3166  if (BtInstance.SearchIndex >= (BtInstance.NoOfFoundDev - 1))
3167  {
3168  // All devices found
3169  #ifdef DEBUG
3170  printf("inquiry done.... exiting \r\n");
3171  #endif
3172 
3173  BtSetup(BtInstance.OldState); // Return to previous state
3174  BtInstance.ScanState = SCAN_OFF;
3175  BtInstance.HciSocket.Busy &= ~HCI_SCAN;
3176  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
3177  }
3178  else
3179  {
3180 
3181  if (SCAN_NAME_STATE == BtInstance.ScanState)
3182  {
3183  BtInstance.SearchIndex++;
3184  BtRequestName();
3185  }
3186  else
3187  {
3188  BtSetup(BtInstance.OldState); // Return to previous state
3189  BtInstance.ScanState = SCAN_OFF;
3190  BtInstance.HciSocket.Busy &= ~HCI_SCAN;
3191  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
3192  }
3193  }
3194  BtInstance.NoOfFoundNames++;
3195  }
3196  else
3197  {
3198  // In all other cases that scanning -> try to update the favourite list with the name
3199  if(!(rn->status))
3200  {
3201  for (Cnt = 0, Exit = FALSE; ((Cnt < MAX_DEV_TABLE_ENTRIES) && (FALSE == Exit)); Cnt++)
3202  {
3203  if (DEV_EMPTY != BtInstance.NonVol.DevList[Cnt].Status)
3204  {
3205  if (0 == bacmp(&(BtInstance.NonVol.DevList[Cnt].Adr), (bdaddr_t*)&(rn->bdaddr)))
3206  {
3207 
3208  #ifdef DEBUG
3209  printf("\r\nUpdated name in favourite list \r\n");
3210  #endif
3211  strcpy(BtInstance.NonVol.DevList[Cnt].Name, (char*)rn->name);
3212 
3213  Exit = TRUE;
3214  }
3215  }
3216  }
3217 
3218  // also update incoming data if it matches
3219  if (0 == bacmp(&(BtInstance.Incoming.Adr), (bdaddr_t*)&(rn->bdaddr)))
3220  {
3221 
3222  #ifdef DEBUG
3223  printf("\r\nUpdated name in favourite list \r\n");
3224  #endif
3225  strcpy(BtInstance.Incoming.Name, (char*)rn->name);
3226  }
3227  }
3228  }
3229  }
3230  break;
3231 
3232  case EVT_DISCONN_COMPLETE:
3233  {
3234  UWORD ConnHandle;
3235  UBYTE Index;
3236 
3237  if (0 == ((evt_disconn_complete*)ptr)->status)
3238  {
3239  ConnHandle = ((evt_disconn_complete*)ptr)->handle;
3240 
3241  if (OK == cBtFindDevConnHandle(ConnHandle, &Index))
3242  {
3243  cBtCloseDevConnection(Index);
3244  if (OK == cBtFindSearchAdr(&(BtInstance.NonVol.DevList[Index].Adr), &Index))
3245  {
3247  }
3248  }
3249  else
3250  {
3251  if (0 == BtInstance.NoOfConnDevs)
3252  {
3253  // Ensure going back to idle if only pairing (no application running on remote device)
3254  // Socket is not going to be established.
3255  BtInstance.PageState = SCAN_PAGE;
3256  BtIssueHciVisible(BtInstance.NonVol.Visible, BtInstance.PageState);
3257  BtInstance.HciSocket.Busy |= HCI_VISIBLE;
3258  }
3259  }
3260  BtInstance.HciSocket.Busy &= ~HCI_DISCONNECT;
3261  }
3262  }
3263  break;
3264 
3265  case EVT_LINK_KEY_NOTIFY:
3266  {
3267  UBYTE DevIndex;
3268  UBYTE SearchIndex;
3269 
3270  if ((0 == ((evt_link_key_notify*)ptr)->key_type) || (5 == ((evt_link_key_notify*)ptr)->key_type))
3271  {
3272  //Only authenticated link keys will result in device table update
3273  if (OK == cBtInsertInDeviceList(&((evt_link_key_notify*)ptr)->bdaddr, &DevIndex))
3274  {
3275  if (I_AM_MASTER == BtInstance.State)
3276  {
3277  #ifdef DEBUG
3278  printf("\r\nEVT_CONN_COMPLETE in master mode: DevIndex = %d, ChNo = %d\r\n",DevIndex, BtInstance.OutGoing.ChNo);
3279  #endif
3280 
3281  BtInstance.NonVol.DevList[DevIndex].ChNo = BtInstance.OutGoing.ChNo;
3282 
3283  if (OK == cBtFindSearchAdr(&((evt_link_key_notify*)ptr)->bdaddr, &SearchIndex))
3284  {
3285  // Insert COD from search list
3286  memcpy(&(BtInstance.NonVol.DevList[DevIndex].DevClass[0]),&(BtInstance.SearchList[SearchIndex].DevClass[0]),3);
3287  }
3288 
3289  }
3290  else
3291  {
3292  // This is I_AM_IN_IDLE
3293  // Connections from the outside (I am a slave) always uses ch 0
3294  BtInstance.NonVol.DevList[DevIndex].ChNo = 0;
3295  memcpy(&(BtInstance.NonVol.DevList[DevIndex].DevClass[0]),&(BtInstance.Incoming.DevClass[0]),3);
3296  strcpy(&(BtInstance.NonVol.DevList[DevIndex].Name[0]),&(BtInstance.Incoming.Name[0]));
3297  BtInstance.NonVol.DevList[DevIndex].ConnHandle = BtInstance.Incoming.ConnHandle;
3298  }
3299  }
3300  }
3301  }
3302  break;
3303 
3304  case EVT_CMD_COMPLETE:
3305  {
3306  switch(((evt_cmd_complete*)ptr)->opcode)
3307  {
3308  case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE):
3309  {
3310  // This is the complete event for visible setting
3311  BtInstance.HciSocket.WaitForEvent = FALSE;
3312  BtInstance.HciSocket.Busy &= ~HCI_VISIBLE;
3313  }
3314  break;
3315 
3316  case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV):
3317  {
3318  // This is the complete event for changing class of device
3319  BtInstance.HciSocket.WaitForEvent = FALSE;
3320  }
3321  break;
3322 
3323  case cmd_opcode_pack(OGF_HOST_CTL, OCF_DELETE_STORED_LINK_KEY):
3324  {
3325  // This is the complete event for deleting link keys
3326  BtInstance.HciSocket.WaitForEvent = FALSE;
3327  }
3328  break;
3329 
3330  case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL):
3331  {
3332  // Inquiry has been cancelled
3333  BtSetup(BtInstance.OldState); // Return to previous state
3334  BtInstance.HciSocket.Busy &= ~HCI_SCAN;
3335  BtInstance.ScanState = SCAN_OFF;
3336  }
3337  break;
3338 
3339  case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME):
3340  {
3341  BtInstance.HciSocket.WaitForEvent = FALSE;
3342  BtInstance.HciSocket.Busy &= ~HCI_NAME;
3343  }
3344  break;
3345 
3346  case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE):
3347  {
3348  BtInstance.HciSocket.WaitForEvent = FALSE;
3349  }
3350  break;
3351 
3352  case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR):
3353  {
3354  // Copy own bluetooth address in place.
3355  // Removed - address now set in init
3356  BtInstance.HciSocket.WaitForEvent = FALSE;
3357  }
3358  break;
3359 
3360  case cmd_opcode_pack(OCF_WRITE_SIMPLE_PAIRING_MODE, WRITE_SIMPLE_PAIRING_MODE_CP_SIZE):
3361  {
3362  BtInstance.HciSocket.WaitForEvent = FALSE;
3363  }
3364  break;
3365 
3366  case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SIMPLE_PAIRING_MODE):
3367  {
3368  BtInstance.HciSocket.WaitForEvent = FALSE;
3369  }
3370  break;
3371 
3372  case cmd_opcode_pack(OGF_HOST_CTL, OCF_RESET):
3373  {
3374  BtInstance.HciSocket.WaitForEvent = FALSE;
3375  }
3376  break;
3377 
3378  case cmd_opcode_pack(OGF_HOST_CTL, OCF_SET_EVENT_MASK):
3379  {
3380  BtInstance.HciSocket.WaitForEvent = FALSE;
3381  }
3382  break;
3383 
3384  case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED):
3385  {
3386  BtInstance.HciSocket.WaitForEvent = FALSE;
3387  }
3388  break;
3389 
3390  case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_EXT_INQUIRY_RESPONSE):
3391  {
3392  BtInstance.HciSocket.WaitForEvent = FALSE;
3393  }
3394  break;
3395 
3396  case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_EXT_INQUIRY_RESPONSE):
3397  {
3398  BtInstance.HciSocket.WaitForEvent = FALSE;
3399  }
3400  break;
3401 
3402  case cmd_opcode_pack(OGF_VENDOR_CMD, 0xFF26):
3403  {
3404  BtInstance.HciSocket.WaitForEvent = FALSE;
3405  }
3406  break;
3407 
3408  default:
3409  {
3410  // Looking for other cmd complete events
3411  }
3412  }
3413  }
3414  break;
3415 
3416  case EVT_ENCRYPT_CHANGE:
3417  {
3418  }
3419  break;
3420 
3421  default:
3422  {
3423  // If we must look for other events....
3424  }
3425  break;
3426  }
3427  }
3428  }
3429  return(RtnVal);
3430 }
3431 
3432 
3434 {
3435  UBYTE RtnVal;
3436 
3437  if (HCI_IDLE == BtInstance.HciSocket.Busy)
3438  {
3439  RtnVal = OK;
3440  }
3441  else
3442  {
3443  if (HCI_FAIL & BtInstance.HciSocket.Busy)
3444  {
3445  RtnVal = FAIL;
3446  }
3447  else
3448  {
3449  RtnVal = BUSY;
3450  }
3451  }
3452  return(RtnVal);
3453 }
3454 
3455 
3457 {
3458  UBYTE Type;
3459 
3460  Type = BTTYPE_UNKNOWN;
3461  if ((0x08 == pCod[1]) && (0x04 == pCod[0]))
3462  {
3463  Type = BTTYPE_BRICK;
3464  }
3465  else
3466  {
3467  if (0x01 == pCod[1])
3468  {
3469  Type = BTTYPE_PC;
3470  }
3471  else
3472  {
3473  if (0x02 == pCod[1])
3474  {
3475  Type = BTTYPE_PHONE;
3476  }
3477  }
3478  }
3479  return(Type);
3480 }
3481 
3482 
3484 {
3485  return(BtInstance.NoOfConnDevs);
3486 }
3487 
3488 
3489 UBYTE cBtGetConnListEntry(UBYTE Item, UBYTE *pName, SBYTE Length, UBYTE *pType)
3490 {
3491  UBYTE ConnCnt = 0;
3492  UBYTE TmpCnt;
3493  UBYTE RtnVal;
3494 
3495  RtnVal = TRUE;
3496  for(TmpCnt = 0; TmpCnt < MAX_DEV_TABLE_ENTRIES; TmpCnt++)
3497  {
3498  if (TRUE == BtInstance.NonVol.DevList[TmpCnt].Connected)
3499  {
3500  if (ConnCnt == Item)
3501  {
3502  snprintf((char*)pName, Length, "%s", (char *)&(BtInstance.NonVol.DevList[TmpCnt].Name[0]));
3503 
3504  *pType = cBtGetBtType(&(BtInstance.NonVol.DevList[TmpCnt].DevClass[0]));
3505  TmpCnt = MAX_DEV_TABLE_ENTRIES;
3506  }
3507  else
3508  {
3509  ConnCnt++;
3510  }
3511  }
3512  }
3513  return(RtnVal);
3514 }
3515 
3516 
3518 {
3519  return(BtInstance.NonVol.DevListEntries);
3520 }
3521 
3522 
3523 UBYTE cBtGetDevListEntry(UBYTE Item, SBYTE *pConnected, SBYTE *pType, UBYTE *pName, SBYTE Length)
3524 {
3525  UBYTE RtnVal;
3526 
3527  snprintf((char*)pName,Length, "%s", (char *)&(BtInstance.NonVol.DevList[Item].Name[0]));
3528  *pConnected = BtInstance.NonVol.DevList[Item].Connected;
3529  *pType = cBtGetBtType(&(BtInstance.NonVol.DevList[Item].DevClass[0]));
3530 
3531  RtnVal = TRUE;
3532  return(RtnVal);
3533 }
3534 
3535 
3537 {
3538  return(BtInstance.NoOfFoundNames);
3539 }
3540 
3541 
3542 UBYTE cBtGetSearchListEntry(UBYTE Item, SBYTE *pConnected, SBYTE *pType, SBYTE *pParred, UBYTE *pName, SBYTE Length)
3543 {
3544  UBYTE RtnVal;
3545 
3546  snprintf((char*)pName,Length, "%s", (char *)&(BtInstance.SearchList[Item].Name[0]));
3547  *pConnected = BtInstance.SearchList[Item].Connected;
3548  *pParred = BtInstance.SearchList[Item].Parred;
3549  *pType = cBtGetBtType(&(BtInstance.SearchList[Item].DevClass[0]));
3550 
3551  RtnVal = TRUE;
3552  return(RtnVal);
3553 }
3554 
3555 
3557 {
3558  UBYTE RtnVal;
3559  UBYTE Cnt, Item;
3560  char Addr[20];
3561 
3562  RtnVal = FAIL;
3563  if (((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy)) && (BLUETOOTH_OFF != BtInstance.State))
3564  {
3565  // Check device list
3566  if (TRUE == cBtFindDevName(&Item, pName, 0))
3567  {
3568  if (DEV_EMPTY != BtInstance.NonVol.DevList[Item].Status)
3569  {
3570  //If item is connected then disconnect it
3571  if(TRUE == BtInstance.NonVol.DevList[Item].Connected)
3572  {
3573  BtInstance.NonVol.DevList[Item].Connected = FALSE;
3574  BtCloseCh(BtInstance.NonVol.DevList[Item].ChNo);
3575  }
3576 
3577  ba2str((bdaddr_t *)(&(BtInstance.NonVol.DevList[Item].Adr.b[0])), Addr);
3578  RemoveDevice(conn, Addr);
3579 
3580  for(Cnt = Item; Cnt < BtInstance.NonVol.DevListEntries; Cnt++)
3581  {
3582  memcpy(&(BtInstance.NonVol.DevList[Cnt].Name[0]), &(BtInstance.NonVol.DevList[Cnt + 1].Name[0]), sizeof(DEVICELIST));
3583  }
3584  if (BtInstance.NonVol.DevListEntries)
3585  {
3586  BtInstance.NonVol.DevListEntries--;
3587  }
3588  BtInstance.NonVol.DevList[Cnt].Status = DEV_EMPTY;
3589  BtInstance.NonVol.DevList[Cnt].Name[0] = 0;
3590  BtInstance.NonVol.DevList[Cnt].Connected = FALSE;
3591  BtInstance.HciSocket.Busy = HCI_IDLE;
3592  RtnVal = TRUE;
3593  }
3594  else
3595  {
3596  // Device list empty
3597  BtInstance.HciSocket.Busy = HCI_FAIL;
3598  }
3599  RtnVal = OK;
3600  }
3601 
3602  // Check search list
3603  if (TRUE == cBtFindSearchName(&Item, pName))
3604  {
3605  for(Cnt = Item; Cnt < BtInstance.NoOfFoundNames; Cnt++)
3606  {
3607  memcpy(&(BtInstance.SearchList[Cnt].Name[0]), &(BtInstance.SearchList[Cnt + 1].Name[0]), sizeof(SEARCHLIST));
3608  }
3609  if (BtInstance.NoOfFoundNames)
3610  {
3611  BtInstance.NoOfFoundNames--;
3612  }
3614  RtnVal = OK;
3615  }
3616  }
3617  return(RtnVal);
3618 }
3619 
3620 
3622 {
3623  UBYTE RtnVal;
3624 
3625  RtnVal = 0;
3626  if (BtInstance.NonVol.On)
3627  {
3628  RtnVal = 0x01;
3629 
3630  if (BtInstance.NonVol.Visible)
3631  {
3632  RtnVal |= 0x02;
3633  }
3634 
3635  if (0 < BtInstance.NoOfConnDevs)
3636  {
3637  RtnVal |= 0x04;
3638  }
3639  }
3640 
3641  return(RtnVal);
3642 }
3643 
3644 
3645 void cBtGetId(UBYTE *pId, UBYTE Length)
3646 {
3647  strncpy((char*)pId, &(BtInstance.Adr[0]), Length);
3648 }
3649 
3650 
3651 UBYTE cBtSetName(UBYTE *pName, UBYTE Length)
3652 {
3653  UBYTE RtnVal = OK;
3654  change_local_name_cp cp;
3655 
3656  if (BLUETOOTH_OFF != BtInstance.State)
3657  {
3658  if ((HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy))
3659  {
3660  snprintf((char *)&(BtInstance.BtName[0]), Length, "%s", (char *)pName);
3661 
3662  snprintf((char *)&(cp.name[0]), Length, "%s", (char *)pName);
3663  hci_send_cmd(BtInstance.HciSocket.Socket, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, &cp);
3664  BtInstance.HciSocket.Busy = HCI_NAME;
3665  }
3666  else
3667  {
3668  RtnVal = FAIL;
3669  }
3670  }
3671  else
3672  {
3673  BtInstance.HciSocket.Busy = HCI_IDLE;
3674  snprintf((char *)&(BtInstance.BtName[0]), Length, "%s", (char *)pName);
3675  }
3676  return(RtnVal);
3677 }
3678 
3679 
3680 UBYTE cBtGetChNo(UBYTE *pName, UBYTE *pChNos)
3681 {
3682  UBYTE RtnVal = 0;
3683  UBYTE Index;
3684  UBYTE Cnt;
3685 
3686  pChNos[RtnVal] = 0;
3687  for(Cnt = 0; Cnt < MAX_DEV_TABLE_ENTRIES; Cnt++)
3688  {
3689  if (cBtFindDevName(&Index, pName, Cnt))
3690  {
3691  if (TRUE == BtInstance.NonVol.DevList[Index].Connected)
3692  {
3693  pChNos[RtnVal] = BtInstance.NonVol.DevList[Index].ChNo;
3694  RtnVal++;
3695  pChNos[RtnVal] = 0;
3696  }
3697  Cnt = Index;
3698  }
3699  else
3700  {
3701  Cnt = MAX_DEV_TABLE_ENTRIES;
3702  }
3703  }
3704  return(RtnVal);
3705 }
3706 
3707 
3708 static char *get_adapter_path(DBusConnection *conn, const char *adapter)
3709 {
3710  DBusMessage *msg, *reply;
3711  DBusError err;
3712  const char *reply_path;
3713  char *path;
3714 
3715  if (!adapter)
3716  return get_default_adapter_path(conn);
3717 
3718  msg = dbus_message_new_method_call("org.bluez", "/",
3719  "org.bluez.Manager", "FindAdapter");
3720 
3721  if (!msg)
3722  {
3723  fprintf(stderr, "Can't allocate new method call\n");
3724  return NULL;
3725  }
3726 
3727  dbus_message_append_args(msg, DBUS_TYPE_STRING, &adapter,
3728  DBUS_TYPE_INVALID);
3729 
3730  dbus_error_init(&err);
3731 
3732  // Next dbus message is blocking
3733  reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
3734 
3735  dbus_message_unref(msg);
3736 
3737  if (!reply)
3738  {
3739  fprintf(stderr, "Can't find adapter %s\n", adapter);
3740  if (dbus_error_is_set(&err))
3741  {
3742  fprintf(stderr, "%s\n", err.message);
3743  dbus_error_free(&err);
3744  }
3745  return NULL;
3746  }
3747 
3748  if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH, &reply_path, DBUS_TYPE_INVALID))
3749  {
3750  fprintf(stderr, "Can't get reply arguments\n");
3751  if (dbus_error_is_set(&err))
3752  {
3753  fprintf(stderr, "%s\n", err.message);
3754  dbus_error_free(&err);
3755  }
3756  return NULL;
3757  }
3758 
3759  path = strdup(reply_path);
3760 
3761  dbus_message_unref(reply);
3762 
3763  dbus_connection_flush(conn);
3764 
3765  return path;
3766 }
3767 
3768 
3769 static DBusHandlerResult request_confirmation_message(DBusConnection *L_conn, DBusMessage *msg, void *data)
3770 {
3771  const char *path;
3772 
3773  conn = L_conn;
3774 
3775  if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
3776  DBUS_TYPE_UINT32, &(BtInstance.Incoming.Passkey), DBUS_TYPE_INVALID))
3777  {
3778  fprintf(stderr, "Invalid arguments for RequestPasskey method");
3779  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3780  }
3781 
3782  // Create both positive and negative reply - user decides later what to use
3783  RejectReply = dbus_message_new_error(msg, "org.bluez.Error.Rejected", "");
3784  reply = dbus_message_new_method_return(msg);
3785  if (!reply)
3786  {
3787  fprintf(stderr, "Can't create reply message\n");
3788  return DBUS_HANDLER_RESULT_NEED_MEMORY;
3789  }
3790 
3791  BtInstance.Events = 0x02;
3792 
3793  return DBUS_HANDLER_RESULT_HANDLED;
3794 }
3795 
3796 
3797 static DBusHandlerResult agent_message(DBusConnection *L_conn, DBusMessage *msg, void *data)
3798 {
3799  if (dbus_message_is_method_call(msg, "org.bluez.Agent", "RequestPinCode"))
3800  {
3801  BtInstance.SspPairingMethod = FALSE;
3802  return request_pincode_message(L_conn, msg, data);
3803  }
3804 
3805  if (dbus_message_is_method_call(msg, "org.bluez.Agent", "RequestPasskey"))
3806  {
3807  // return request_passkey_message(conn, msg, data);
3808  }
3809 
3810  if (dbus_message_is_method_call(msg, "org.bluez.Agent", "RequestConfirmation"))
3811  {
3812  BtInstance.SspPairingMethod = TRUE;
3813  return request_confirmation_message(L_conn, msg, data);
3814  }
3815 
3816  if (dbus_message_is_method_call(msg, "org.bluez.Agent", "Authorize"))
3817  {
3818  // return authorize_message(conn, msg, data);
3819  }
3820 
3821  if (dbus_message_is_method_call(msg, "org.bluez.Agent", "Cancel"))
3822  {
3823 // return cancel_message(conn, msg, data);
3824  }
3825 
3826  if (dbus_message_is_method_call(msg, "org.bluez.Agent", "Release"))
3827  {
3828 // return release_message(conn, msg, data);
3829  }
3830 
3831  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3832 }
3833 
3834 
3835 static int register_agent(DBusConnection *conn, const char *adapter_path, const char *agent_path, const char *capabilities)
3836 {
3837  DBusMessage *msg, *reply;
3838  DBusError err;
3839  int RtnVal;
3840 
3841  RtnVal = 0;
3842 
3843  msg = dbus_message_new_method_call("org.bluez", adapter_path, "org.bluez.Adapter", "RegisterAgent");
3844  if (!msg)
3845  {
3846  #ifdef DEBUG
3847  fprintf(stderr, "Can't allocate new method call\n");
3848  #endif
3849  RtnVal = -1;
3850  }
3851  else
3852  {
3853  dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path, DBUS_TYPE_STRING, &capabilities, DBUS_TYPE_INVALID);
3854  dbus_error_init(&err);
3855 
3856  // Next dbus message is blocking
3857  reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
3858  dbus_message_unref(msg);
3859 
3860  if (!reply)
3861  {
3862  #ifdef DEBUG
3863  fprintf(stderr, "Can't register agent\n");
3864  #endif
3865  if (dbus_error_is_set(&err))
3866  {
3867  fprintf(stderr, "%s\n", err.message);
3868  dbus_error_free(&err);
3869  }
3870  RtnVal = -1;
3871  }
3872  else
3873  {
3874  dbus_message_unref(reply);
3875  dbus_connection_flush(conn);
3876  }
3877  }
3878  return(RtnVal);
3879 }
3880 
3881 
3882 static DBusHandlerResult agent_filter(DBusConnection *conn, DBusMessage *msg, void *data)
3883 {
3884  const char *name, *old, *new;
3885 
3886  if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
3887  {
3888  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3889  }
3890 
3891  if (!dbus_message_get_args(msg, NULL,
3892  DBUS_TYPE_STRING, &name,
3893  DBUS_TYPE_STRING, &old,
3894  DBUS_TYPE_STRING, &new,
3895  DBUS_TYPE_INVALID))
3896  {
3897  fprintf(stderr, "Invalid arguments for NameOwnerChanged signal");
3898  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3899  }
3900 
3901  if (!strcmp(name, "org.bluez") && *new == '\0')
3902  {
3903  fprintf(stderr, "Agent has been terminated\n");
3904  __io_terminated = 1;
3905  }
3906 
3907  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3908 }
3909 
3910 
3911 static DBusHandlerResult request_pincode_message(DBusConnection *conn, DBusMessage *msg, void *data)
3912 {
3913  const char *path;
3914  DBusHandlerResult Result;
3915  UBYTE *pPin;
3916 
3917  if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
3918  {
3919  #ifdef DEBUG
3920  fprintf(stderr, "Invalid arguments for RequestPinCode method");
3921  #endif
3922  Result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3923  }
3924  else
3925  {
3926  reply = dbus_message_new_method_return(msg);
3927  if (!reply)
3928  {
3929  #ifdef DEBUG
3930  fprintf(stderr, "Can't create reply message\r\n");
3931  #endif
3932  Result = DBUS_HANDLER_RESULT_NEED_MEMORY;
3933  }
3934  else
3935  {
3936 
3937  // If remote device is trusted then automatically
3938  // add the pin code
3939  if (TRUE == BtInstance.TrustedDev.Status)
3940  {
3941  // This request is the trusted one - evaluated by the hci pin request event
3942  pPin = BtInstance.TrustedDev.Pin;
3943 
3944  dbus_message_append_args(reply, DBUS_TYPE_STRING, &pPin, DBUS_TYPE_INVALID);
3945  dbus_connection_send(conn, reply, NULL);
3946  dbus_connection_flush(conn);
3947  dbus_message_unref(reply);
3948 
3949  BtInstance.TrustedDev.Status = FALSE; //Only one trusted pin per pin event
3950  }
3951  else
3952  {
3953  BtInstance.Events = 1;
3954  Result = DBUS_HANDLER_RESULT_HANDLED;
3955  }
3956  }
3957  }
3958  return(Result);
3959 }
3960 
3961 
3962 static char *get_default_adapter_path(DBusConnection *conn)
3963 {
3964  DBusMessage *msg, *reply;
3965  DBusError err;
3966  const char *reply_path;
3967  char *path;
3968 
3969  msg = dbus_message_new_method_call("org.bluez", "/", "org.bluez.Manager", "DefaultAdapter");
3970 
3971  if (!msg)
3972  {
3973  fprintf(stderr, "Can't allocate new method call\n");
3974  return NULL;
3975  }
3976 
3977  dbus_error_init(&err);
3978 
3979  reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
3980 
3981  dbus_message_unref(msg);
3982 
3983  if (!reply)
3984  {
3985  fprintf(stderr, "Can't get default adapter\n");
3986  if (dbus_error_is_set(&err))
3987  {
3988  fprintf(stderr, "%s\n", err.message);
3989  dbus_error_free(&err);
3990  }
3991  return NULL;
3992  }
3993 
3994  if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH, &reply_path, DBUS_TYPE_INVALID))
3995  {
3996  fprintf(stderr, "Can't get reply arguments\n");
3997  if (dbus_error_is_set(&err))
3998  {
3999  fprintf(stderr, "%s\n", err.message);
4000  dbus_error_free(&err);
4001  }
4002  return NULL;
4003  }
4004 
4005  path = strdup(reply_path);
4006 
4007  dbus_message_unref(reply);
4008 
4009  dbus_connection_flush(conn);
4010 
4011  return path;
4012 }
4013 
4014 
4015 static int RemoveDevice(DBusConnection *conn, char *Device)
4016 {
4017  DBusMessage *msg, *reply;
4018  DBusError err;
4019  char *Path;
4020  const char *reply_path;
4021  int RtnVal;
4022 
4023  RtnVal = 0;
4024 
4025  msg = dbus_message_new_method_call("org.bluez", adapter_path, "org.bluez.Adapter", "FindDevice");
4026  if (!msg)
4027  {
4028  fprintf(stderr, "Can't allocate new method call\n");
4029  RtnVal = -1;
4030  }
4031  else
4032  {
4033 
4034  dbus_message_append_args(msg, DBUS_TYPE_STRING, &Device, DBUS_TYPE_INVALID);
4035  dbus_error_init(&err);
4036 
4037  // Next dbus message is a blocking call
4038  reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
4039  dbus_message_unref(msg);
4040 
4041  if (!reply)
4042  {
4043  #ifdef DEBUG
4044  fprintf(stderr, "Can't register agent\r\n");
4045  #endif
4046  if (dbus_error_is_set(&err))
4047  {
4048  #ifdef DEBUG
4049  fprintf(stderr, "%s \r\n", err.message);
4050  #endif
4051  dbus_error_free(&err);
4052  }
4053  RtnVal = -1;
4054  }
4055  else
4056  {
4057 
4058  if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH, &reply_path, DBUS_TYPE_INVALID))
4059  {
4060  #ifdef DEBUG
4061  fprintf(stderr, "Can't get reply arguments\n");
4062  #endif
4063 
4064  if (dbus_error_is_set(&err))
4065  {
4066  #ifdef DEBUG
4067  fprintf(stderr, "%s\n", err.message);
4068  #endif
4069 
4070  dbus_error_free(&err);
4071  }
4072  RtnVal = -1;
4073  }
4074  else
4075  {
4076  dbus_connection_flush(conn);
4077 
4078  Path = strdup(reply_path);
4079  dbus_message_unref(reply);
4080 
4081  msg = dbus_message_new_method_call("org.bluez", adapter_path, "org.bluez.Adapter", "RemoveDevice");
4082  if (!msg)
4083  {
4084  #ifdef DEBUG
4085  fprintf(stderr, "Can't allocate new method call\n");
4086  #endif
4087  RtnVal = -1;
4088  }
4089  else
4090  {
4091 
4092  dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &Path, DBUS_TYPE_INVALID);
4093  dbus_error_init(&err);
4094 
4095  // Next dbus message is blocking
4096  reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
4097  dbus_message_unref(msg);
4098 
4099  if (!reply)
4100  {
4101  #ifdef DEBUG
4102  fprintf(stderr, "Can't register agent\n");
4103  #endif
4104  if (dbus_error_is_set(&err))
4105  {
4106  #ifdef DEBUG
4107  fprintf(stderr, "%s\n", err.message);
4108  #endif
4109  dbus_error_free(&err);
4110  }
4111  RtnVal = -1;
4112  }
4113  else
4114  {
4115  dbus_message_unref(reply);
4116  dbus_connection_flush(conn);
4117  }
4118  }
4119  free(Path);
4120  }
4121  }
4122  }
4123 
4124  return(RtnVal);
4125 }
4126 
4127 
4128 static void sig_term(int sig)
4129 {
4130  __io_canceled = 1;
4131 }
4132 
4133 
4134 static int unregister_agent(DBusConnection *conn, const char *adapter_path, const char *agent_path)
4135 {
4136  DBusMessage *msg, *reply;
4137  DBusError err;
4138 
4139  msg = dbus_message_new_method_call("org.bluez", adapter_path, "org.bluez.Adapter", "UnregisterAgent");
4140  if (!msg)
4141  {
4142  #ifdef DEBUG
4143  fprintf(stderr, "Can't allocate new method call\n");
4144  #endif
4145  return -1;
4146  }
4147 
4148  dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path, DBUS_TYPE_INVALID);
4149  dbus_error_init(&err);
4150  reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
4151  dbus_message_unref(msg);
4152 
4153  if (!reply)
4154  {
4155  #ifdef DEBUG
4156  fprintf(stderr, "Can't unregister agent\n");
4157  #endif
4158  if (dbus_error_is_set(&err))
4159  {
4160  fprintf(stderr, "%s\n", err.message);
4161  dbus_error_free(&err);
4162  }
4163  return -1;
4164  }
4165 
4166  dbus_message_unref(reply);
4167  dbus_connection_flush(conn);
4168  dbus_connection_unregister_object_path(conn, agent_path);
4169 
4170  return 0;
4171 }
4172 
4173 
4175 {
4176  UBYTE Evt;
4177 
4178  Evt = BtInstance.Events;
4179  BtInstance.Events = 0;
4180  return(Evt);
4181 }
4182 
4183 
4184 void cBtGetIncoming(UBYTE *pName, UBYTE *pCod, UBYTE Len)
4185 {
4186  snprintf((char*)pName, Len, "%s", &(BtInstance.Incoming.Name[0]));
4187  *pCod = cBtGetBtType(&(BtInstance.Incoming.DevClass[0]));
4188 }
4189 
4190 
4192 {
4193  UBYTE RtnVal = OK;
4194 
4195  // Pin can be set both when connecting as master or slave
4196  if (((HCI_CONNECT == BtInstance.HciSocket.Busy) || (HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy)) &&
4197  (BLUETOOTH_OFF != BtInstance.State))
4198  {
4199  dbus_message_append_args(reply, DBUS_TYPE_STRING, &pPin, DBUS_TYPE_INVALID);
4200  dbus_connection_send(conn, reply, NULL);
4201  dbus_connection_flush(conn);
4202  dbus_message_unref(reply);
4203  }
4204  else
4205  {
4206  RtnVal = FAIL;
4207  }
4208  return(RtnVal);
4209 }
4210 
4211 
4213 {
4214  UBYTE RtnVal = OK;
4215 
4216  // Pin can be set both when connecting as master or slave
4217  if (((HCI_CONNECT == BtInstance.HciSocket.Busy) || (HCI_IDLE == BtInstance.HciSocket.Busy) || (HCI_FAIL == BtInstance.HciSocket.Busy)) &&
4218  (BLUETOOTH_OFF != BtInstance.State))
4219  {
4220  if (Accept)
4221  {
4222  dbus_connection_send(conn, reply, NULL);
4223  dbus_connection_flush(conn);
4224  dbus_message_unref(reply);
4225  }
4226  else
4227  {
4228  dbus_connection_send(conn, RejectReply, NULL);
4229  dbus_connection_flush(conn);
4230  dbus_message_unref(RejectReply);
4231  }
4232  }
4233  else
4234  {
4235  RtnVal = FAIL;
4236  }
4237  return(RtnVal);
4238 }
4239 
4240 void cBtSetTrustedDev(UBYTE *pBtAddr, UBYTE *pPin, UBYTE PinSize)
4241 {
4242 
4243  BtInstance.TrustedDev.PinLen = PinSize;
4244  snprintf((char*)&(BtInstance.TrustedDev.Pin[0]), 7, "%s", pPin);
4245  cBtStrNoColonToBa(pBtAddr, &(BtInstance.TrustedDev.Adr));
4246 }
4247 
4248 
4249 void cBtStrNoColonToBa(UBYTE *pBtStrAddr, bdaddr_t *pAddr)
4250 {
4251  ULONG Ba[6];
4252 
4253  sscanf((char *)pBtStrAddr,"%2X%2X%2X%2X%2X%2X", &(Ba[5]), &(Ba[4]), &(Ba[3]), &(Ba[2]), &(Ba[1]), &(Ba[0]));
4254 
4255  // To avoid alignment faults casting to lower size is necessary
4256  pAddr->b[5] = (uint8_t)Ba[5];
4257  pAddr->b[4] = (uint8_t)Ba[4];
4258  pAddr->b[3] = (uint8_t)Ba[3];
4259  pAddr->b[2] = (uint8_t)Ba[2];
4260  pAddr->b[1] = (uint8_t)Ba[1];
4261  pAddr->b[0] = (uint8_t)Ba[0];
4262 }
4263 
4264 
4266 {
4267  UWORD RtnVal;
4268 
4269  RtnVal = FALSE;
4270  if (MAX_BUNDLE_ID_SIZE > strlen((char*)pId))
4271  {
4272  snprintf((char*)&BtInstance.NonVol.BundleID[0], MAX_BUNDLE_ID_SIZE, "%s", (char*)pId);
4273  RtnVal = TRUE;
4274  }
4275 
4276  return(RtnVal);
4277 }
4278 
4280 {
4281  UWORD RtnVal;
4282 
4283  RtnVal = FALSE;
4284  if (MAX_BUNDLE_SEED_ID_SIZE > strlen((char*)pSeedId))
4285  {
4286  snprintf((char*)&BtInstance.NonVol.BundleSeedID[0], MAX_BUNDLE_SEED_ID_SIZE, "%s", (char*)pSeedId);
4287  RtnVal = TRUE;
4288  }
4289 
4290  return(RtnVal);
4291 }
4292 
4293 
4294 
4295 
void BtSetupPinEvent(void)
Definition: c_bt.c:261
void BtUpdate(void)
Definition: c_bt.c:1572
struct timeval Cmdtv
Definition: c_bt.h:159
UWORD cBtSetBundleSeedId(UBYTE *pSeedId)
Definition: c_bt.c:4279
void cBtClearSearchConnectedStatus(UBYTE Index)
Definition: c_bt.c:2830
BT_GLOBALS * gBtInstance
Definition: c_bt.c:164
UWORD cBtReadCh2(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:749
UBYTE cBtSetName(UBYTE *pName, UBYTE Length)
Definition: c_bt.c:3651
TRUSTED_DEV TrustedDev
Definition: c_bt.h:247
UBYTE cBtI2cBufReady(void)
Definition: c_bt.c:2523
READBUF ReadBuf
Definition: c_bt.h:191
struct sockaddr_rc loc_addr
Definition: c_bt.h:148
Definition: c_bt.h:74
UBYTE cBtGetChNo(UBYTE *pName, UBYTE *pChNos)
Definition: c_bt.c:3680
UBYTE BtConnectTo(UBYTE Port, bdaddr_t BtAddr)
Definition: c_bt.c:1910
Definition: c_bt.h:123
UWORD Status
Definition: c_bt.h:129
UWORD InPtr
Definition: c_bt.h:106
UWORD ConnHandle
Definition: c_bt.h:212
UBYTE cBtConnect(UBYTE *pDevName)
Definition: c_bt.c:2276
Definition: lms2012.h:558
#define snprintf
Definition: c_input.c:141
UWORD cBtDevWriteBuf6(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2652
UBYTE ChNo
Definition: c_bt.h:220
void cBtSetDevConnectedStatus(UBYTE Index)
Definition: c_bt.c:2806
void BtSetup(UBYTE State)
cBtSetup
Definition: c_bt.c:511
NONVOLBT NonVol
Definition: c_bt.h:259
UBYTE cBtDisconnect(UBYTE *pName)
Definition: c_bt.c:2415
UBYTE BtStartScan(void)
Definition: c_bt.c:646
BTSOCKET BtSocket
Definition: c_bt.h:193
UBYTE BundleID[MAX_BUNDLE_ID_SIZE]
Definition: c_bt.h:205
signed char SBYTE
Basic Type used to symbolise 8 bit signed values.
Definition: lmstypes.h:33
UBYTE PinLen
Definition: c_bt.h:226
Definition: c_bt.h:155
void BtClose(void)
Definition: c_bt.c:1529
SLONG Socket
Definition: c_bt.h:147
Definition: c_bt.c:207
UWORD OutPtr
Definition: c_bt.h:107
UBYTE cBtFindDevAdr(bdaddr_t *pAdr, UBYTE *pIndex)
Definition: c_bt.c:2700
UWORD cBtDevWriteBuf2(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2592
bdaddr_t Adr
Definition: c_bt.h:225
UWORD ConnHandle
Definition: c_bt.h:168
UBYTE BtSetOnOff(UBYTE On)
Definition: c_bt.c:2000
Definition: c_bt.h:98
UBYTE Connected
Definition: c_bt.h:182
UWORD cBtReadCh3(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:771
UBYTE BtGetVisibility(void)
Definition: c_bt.c:2114
void DecodeMode1(UBYTE BufNo)
Definition: c_bt.c:920
UBYTE cBtGetConnListEntry(UBYTE Item, UBYTE *pName, SBYTE Length, UBYTE *pType)
Definition: c_bt.c:3489
UBYTE BtSetMode2(UBYTE Mode2)
Definition: c_bt.c:1936
UBYTE cBtFindSearchAdr(bdaddr_t *pAdr, UBYTE *pIndex)
Definition: c_bt.c:2682
void create_paired_device_reply(DBusPendingCall *pending, void *user_data)
Definition: c_bt.c:1837
char Name[MAX_BT_NAME_SIZE]
Definition: c_bt.h:179
UBYTE cBtFindDevName(UBYTE *pItem, UBYTE *pName, UBYTE StartIndex)
Definition: c_bt.c:2120
#define MAX_DEV_TABLE_ENTRIES
Definition: c_bt.h:36
SLONG OldState
Definition: c_bt.h:257
UWORD cBtReadCh5(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:815
UWORD RemMsgLen
Definition: c_bt.h:128
void BtTurnOnSeq(void)
Definition: c_bt.c:1207
UWORD cBtDevWriteBuf7(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2667
void BtTurnOffSeq(void)
Definition: c_bt.c:1561
UBYTE cBtGetHciBusyFlag(void)
Definition: c_bt.c:3433
#define LEGO_BUNDLE_SEED_ID
Definition: c_bt.c:179
Definition: c_bt.h:93
UBYTE BtIssueHciVisible(UBYTE Visible, UBYTE Page)
Definition: c_bt.c:2052
INCOMMING Incoming
Definition: c_bt.h:245
UWORD cBtDevWriteBuf3(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2607
UBYTE Buf[1024]
Definition: c_bt.h:105
Definition: lms2012.h:557
SLONG State
Definition: c_bt.h:256
void setOutputInstance(BT_GLOBALS *_Instance)
Definition: c_bt.c:166
LISTENSOCKET ListenSocket
Definition: c_bt.h:239
UBYTE BtGetOnOff(UBYTE *On)
Definition: c_bt.c:2042
UBYTE cBtGetDevListEntry(UBYTE Item, SBYTE *pConnected, SBYTE *pType, UBYTE *pName, SBYTE Length)
Definition: c_bt.c:3523
UBYTE cBtSetPin(UBYTE *pPin)
Definition: c_bt.c:4191
UBYTE cBtDiscChNo(UBYTE ChNo)
Definition: c_bt.c:2396
UWORD DataToMode2Decoding(UBYTE *pBuf, UWORD Length)
Definition: c_i2c.c:776
UBYTE Busy
Definition: c_bt.h:140
char BtName[vmBRICKNAMESIZE]
Definition: c_bt.h:265
char Name[MAX_BT_NAME_SIZE]
Definition: c_bt.h:213
UBYTE Visible
Definition: c_bt.h:202
UWORD MsgLen
Definition: c_bt.h:127
UBYTE cBtFindDevChNo(UBYTE ChNo, UBYTE *pIndex)
Definition: c_bt.c:2739
void DecodeBtStream(UBYTE BufNo)
Definition: c_bt.c:879
UBYTE WaitForEvent
Definition: c_bt.h:139
void I2cStop(void)
Definition: c_i2c.c:213
UBYTE cBtGetNoOfDevListEntries(void)
Definition: c_bt.c:3517
UBYTE DecodeMode
Definition: c_bt.h:204
bdaddr_t Adr
Definition: c_bt.h:214
UBYTE Connect(bdaddr_t BdAddr, UBYTE PortNo)
Definition: c_bt.c:2187
UBYTE PageState
Definition: c_bt.h:252
MSGBUF MsgBuf
Definition: c_bt.h:192
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
Definition: lmstypes.h:31
bdaddr_t Adr
Definition: c_bt.h:180
UBYTE Status
Definition: c_bt.h:194
UWORD cBtReadCh0(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:706
Definition: c_bt.h:63
void BtCloseCh(UBYTE ChIndex)
Definition: c_bt.c:453
Definition: c_bt.c:189
ULONG opt
Definition: c_bt.h:150
UBYTE NoOfFoundDev
Definition: c_bt.h:250
UBYTE SspPairingMethod
Definition: c_bt.h:264
UBYTE NoOfFoundNames
Definition: c_bt.h:251
void cBtSetTrustedDev(UBYTE *pBtAddr, UBYTE *pPin, UBYTE PinSize)
Definition: c_bt.c:4240
Definition: c_bt.h:62
UBYTE BtClearSearchListEntry(UBYTE Index)
Definition: c_bt.c:2151
UWORD cBtSetBundleId(UBYTE *pId)
Definition: c_bt.c:4265
UWORD cBtReadCh6(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:837
char Name[MAX_BT_NAME_SIZE]
Definition: c_bt.h:166
Definition: c_bt.h:113
Definition: c_bt.h:83
ULONG Passkey
Definition: c_bt.h:211
UWORD cBtDevWriteBuf(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2547
Definition: c_bt.h:90
void BtSetupHciSocket(void)
Definition: c_bt.c:248
UWORD BtRequestName(void)
Definition: c_bt.c:629
HCISOCKET HciSocket
Definition: c_bt.h:238
UBYTE cBtDeleteFavourItem(UBYTE *pName)
Definition: c_bt.c:3556
#define MAX_BUNDLE_ID_SIZE
Definition: c_bt.h:41
OUTGOING OutGoing
Definition: c_bt.h:246
void DecodeMode2(void)
Definition: c_bt.c:893
Definition: c_bt.h:94
UBYTE cBtGetStatus(void)
Definition: c_bt.c:3621
UWORD cBtReadCh4(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:793
WRITEBUF WriteBuf
Definition: c_bt.h:190
void BtDisconnectAll(void)
Definition: c_bt.c:481
void BtCloseBtSocket(SLONG *pBtSocket)
Definition: c_bt.c:443
void BtTxMsgs(void)
Definition: c_bt.c:2461
UBYTE BtStopScan(void)
Definition: c_bt.c:664
UBYTE cBtGetSearchListEntry(UBYTE Item, SBYTE *pConnected, SBYTE *pType, SBYTE *pParred, UBYTE *pName, SBYTE Length)
Definition: c_bt.c:3542
void cBtGetId(UBYTE *pId, UBYTE Length)
Definition: c_bt.c:3645
UBYTE cBtGetNoOfConnListEntries(void)
Definition: c_bt.c:3483
UBYTE ScanState
Definition: c_bt.h:253
bdaddr_t Adr
Definition: c_bt.h:167
ULONG Delay
Definition: c_bt.h:258
UBYTE DevListEntries
Definition: c_bt.h:201
UBYTE Parred
Definition: c_bt.h:183
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
UBYTE cBtDiscDevIndex(UBYTE Index)
Definition: c_bt.c:2381
UWORD cBtHandleHCI(void)
cBtHandleHCI
Definition: c_bt.c:2907
UBYTE Status
Definition: c_bt.h:173
UWORD cBtReadCh1(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:727
UBYTE Buf[1024]
Definition: c_bt.h:125
UWORD InPtr
Definition: c_bt.h:126
UWORD cBtI2cToBtBuf(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2536
UBYTE cBtInsertInDeviceList(bdaddr_t *pBtAdr, UBYTE *pIndex)
Definition: c_bt.c:2759
void SetupListeningSocket(int *Socket)
Definition: c_bt.c:295
DEVICELIST DevList[MAX_DEV_TABLE_ENTRIES]
Definition: c_bt.h:200
UBYTE cBtGetNoOfSearchListEntries(void)
Definition: c_bt.c:3536
UBYTE DevClass[3]
Definition: c_bt.h:169
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
Definition: lmstypes.h:30
void I2cExit(void)
Definition: c_i2c.c:188
BTCH BtCh[NO_OF_BT_CHS]
Definition: c_bt.h:240
UBYTE RestartSeqCnt
Definition: c_bt.h:261
UBYTE DevClass[3]
Definition: c_bt.h:215
void cBtGetIncoming(UBYTE *pName, UBYTE *pCod, UBYTE Len)
Definition: c_bt.c:4184
UBYTE create_paired_device(DBusConnection *conn, const char *adapter_path, const char *agent_path, const char *capabilities, const char *device, UBYTE Port)
Definition: c_bt.c:1865
Definition: c_bt.h:103
UBYTE cBtSetPasskey(UBYTE Accept)
Definition: c_bt.c:4212
void BtExit(void)
Definition: c_bt.c:426
READBUF Mode2Buf
Definition: c_bt.h:241
signed short SWORD
Basic Type used to symbolise 16 bit signed values.
Definition: lmstypes.h:34
BT_GLOBALS * getBtInstance()
Definition: c_bt.c:171
void cBtInsertDevConnHandle(UBYTE Index, UWORD ConnHandle)
Definition: c_bt.c:2836
WRITEBUF Mode2WriteBuf
Definition: c_bt.h:242
Definition: c_bt.c:190
SLONG Socket
Definition: c_bt.h:137
UBYTE Connected
Definition: c_bt.h:171
SEARCHLIST SearchList[MAX_DEV_TABLE_ENTRIES]
Definition: c_bt.h:244
UWORD Status
Definition: c_bt.h:108
UWORD InPtr
Definition: c_bt.h:116
#define LEGO_BUNDLE_ID
Definition: c_bt.c:180
RESULT I2cInit(READBUF *pBuf, WRITEBUF *pWriteBuf, char *pBundleId, char *pBundleSeedId)
Definition: c_i2c.c:168
struct pollfd p
Definition: c_bt.h:138
UWORD cBtDevWriteBuf4(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2622
UBYTE cBtGetEvent(void)
Definition: c_bt.c:4174
void BtInit(char *pName)
Definition: c_bt.c:349
void cBtCloseDevConnection(UBYTE Index)
Definition: c_bt.c:2813
UBYTE BundleSeedID[MAX_BUNDLE_SEED_ID_SIZE]
Definition: c_bt.h:206
void I2cStart(void)
Definition: c_i2c.c:198
UBYTE cBtFindSearchName(UBYTE *pItem, UBYTE *pName)
Definition: c_bt.c:2168
UWORD cBtDevWriteBuf1(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2577
UWORD OutPtr
Definition: c_bt.h:117
UBYTE DevClass[3]
Definition: c_bt.h:181
UBYTE Events
Definition: c_bt.h:262
SLONG Socket
Definition: c_bt.h:157
UBYTE BtGetMode2(UBYTE *pMode2)
Definition: c_bt.c:1990
UBYTE ChNo
Definition: c_bt.h:172
UBYTE BtSetVisibility(UBYTE State)
Definition: c_bt.c:2076
UBYTE Pin[10]
Definition: c_bt.h:227
UBYTE cBtFindDevConnHandle(UBYTE ConnHandle, UBYTE *pIndex)
Definition: c_bt.c:2719
void BtClearChBuf(UBYTE ChNo)
Definition: c_bt.c:327
void cBtSetSearchConnectedStatus(UBYTE Index)
Definition: c_bt.c:2823
char Adr[13]
Definition: c_bt.h:248
UBYTE On
Definition: c_bt.h:203
UBYTE Buf[1024]
Definition: c_bt.h:115
UBYTE Status
Definition: c_bt.h:228
struct sockaddr_rc rem_addr
Definition: c_bt.h:149
Definition: c_bt.c:206
void cBtStrNoColonToBa(UBYTE *pBtStrAddr, bdaddr_t *pAddr)
Definition: c_bt.c:4249
UBYTE cBtGetBtType(UBYTE *pCod)
Definition: c_bt.c:3456
bdaddr_t Addr
Definition: c_bt.h:158
UBYTE LargeMsg
Definition: c_bt.h:130
signed int SLONG
Basic Type used to symbolise 32 bit signed values.
Definition: lmstypes.h:35
UWORD cBtDevWriteBuf5(UBYTE *pBuf, UWORD Size)
Definition: c_bt.c:2637
UBYTE SearchIndex
Definition: c_bt.h:249
#define MAX_BUNDLE_SEED_ID_SIZE
Definition: c_bt.h:42
UBYTE NoOfConnDevs
Definition: c_bt.h:254
fd_set Cmdfds
Definition: c_bt.h:160
Definition: c_bt.h:91
Definition: c_bt.c:191
#define NULL
UWORD cBtReadCh7(UBYTE *pBuf, UWORD Length)
Definition: c_bt.c:858
#define NONVOL_BT_DATA
Definition: c_bt.h:33
UBYTE OnOffSeqCnt
Definition: c_bt.h:260