3737import java .nio .ByteBuffer ;
3838
3939import com .augmentos .smartglassesmanager .SmartGlassesAndroidService ;
40+ import com .augmentos .smartglassesmanager .eventbusmessages .HeadUpAngleEvent ;
4041import com .augmentos .smartglassesmanager .utils .SmartGlassesConnectionState ;
4142import com .google .gson .Gson ;
4243import com .augmentos .augmentoslib .events .AudioChunkNewEvent ;
@@ -352,8 +353,8 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
352353
353354 if (isLeftConnected && isRightConnected ) {
354355 //no idea why but it's in the Even app - Cayden
355- Log .d (TAG , "Sending 0xF4 Command" );
356- sendDataSequentially (new byte []{(byte ) 0xF4 , (byte ) 0x01 });
356+ // Log.d(TAG, "Sending 0xF4 Command");
357+ // sendDataSequentially(new byte[]{(byte) 0xF4, (byte) 0x01});
357358
358359 //no longer need to be staggered as we fixed the sender
359360 //do first battery status query
@@ -391,13 +392,13 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
391392 @ Override
392393 public void onCharacteristicWrite (BluetoothGatt gatt , BluetoothGattCharacteristic characteristic , int status ) {
393394 if (status == BluetoothGatt .GATT_SUCCESS ) {
394- // Log.d(TAG, side + " glass write successful");
395+ Log .d (TAG , side + " glass write successful" );
395396 } else {
396397 Log .e (TAG , side + " glass write failed with status: " + status );
397398
398399 if (status == 133 ) {
399400 Log .d (TAG , "GOT THAT 133 STATUS!" );
400-
401+
401402 }
402403 }
403404
@@ -474,7 +475,7 @@ else if (data.length > 1 && (data[0] & 0xFF) == 0xF5 && (data[1] & 0xFF) == 0x02
474475 else if (data .length > 1 && (data [0 ] & 0xFF ) == 0xF5 && (data [1 ] & 0xFF ) == 0x03 ) {
475476 if (deviceName .contains ("R_" )) {
476477 // Log.d(TAG, "HEAD DOWN MOVEMENT DETECTED");
477- // clearBmpDisplay();
478+ // clearBmpDisplay();
478479 EventBus .getDefault ().post (new GlassesHeadDownEvent ());
479480
480481 }
@@ -504,27 +505,27 @@ else if (data.length > 0 && data[0] == 0x25) {
504505 }
505506
506507 private void enableNotification (BluetoothGatt gatt , BluetoothGattCharacteristic characteristic , String side ) {
507- gatt .setCharacteristicNotification (characteristic , true );
508- BluetoothGattDescriptor descriptor = characteristic .getDescriptor (CLIENT_CHARACTERISTIC_CONFIG_UUID );
509- if (descriptor != null ) {
510- descriptor .setValue (BluetoothGattDescriptor .ENABLE_NOTIFICATION_VALUE );
511- if ("Left" .equals (side )) {
512- leftServicesWaiter .setTrue ();
513- } else {
514- rightServicesWaiter .setTrue ();
515- }
516- boolean result = gatt .writeDescriptor (descriptor );
517- if (result ) {
518- Log .d (TAG , side + " SIDE," + "Descriptor write successful for characteristic: " + characteristic .getUuid ());
519- if ("Left" .equals (side )) isLeftConnected = true ;
520- else isRightConnected = true ;
521- updateConnectionState ();
522- } else {
523- Log .e (TAG , side + " SIDE," + "Failed to write descriptor for characteristic: " + characteristic .getUuid ());
524- }
508+ Log .d (TAG , "PROC_QUEUE - Starting notification setup for " + side );
509+
510+ // Simply enable notifications
511+ boolean result = gatt .setCharacteristicNotification (characteristic , true );
512+ Log .d (TAG , "PROC_QUEUE - setCharacteristicNotification result for " + side + ": " + result );
513+
514+ // Set write type for the characteristic
515+ characteristic .setWriteType (BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT );
516+ Log .d (TAG , "PROC_QUEUE - write type set for " + side );
517+
518+ // Mark as connected and release waiter immediately
519+ if ("Left" .equals (side )) {
520+ isLeftConnected = true ;
521+ leftServicesWaiter .setFalse ();
522+ Log .d (TAG , "PROC_QUEUE - left side setup complete" );
525523 } else {
526- Log .e (TAG , side + " SIDE," + "Descriptor not found for characteristic: " + characteristic .getUuid ());
524+ isRightConnected = true ;
525+ rightServicesWaiter .setFalse ();
526+ Log .d (TAG , "PROC_QUEUE - right side setup complete" );
527527 }
528+ updateConnectionState ();
528529 }
529530
530531 private void updateConnectionState () {
@@ -639,10 +640,10 @@ public String parsePairingIdFromDeviceName(String input) {
639640 }
640641
641642 public static void savePreferredG1DeviceId (Context context , String deviceName ){
642- context .getSharedPreferences (SHARED_PREFS_NAME , Context .MODE_PRIVATE )
643- .edit ()
644- .putString (SAVED_G1_ID_KEY , deviceName )
645- .apply ();
643+ context .getSharedPreferences (SHARED_PREFS_NAME , Context .MODE_PRIVATE )
644+ .edit ()
645+ .putString (SAVED_G1_ID_KEY , deviceName )
646+ .apply ();
646647 }
647648
648649 public static String getPreferredG1DeviceId (Context context ){
@@ -826,11 +827,11 @@ public void onScanResult(int callbackType, ScanResult result) {
826827
827828 connectHandler .postDelayed (() -> {
828829 attemptGattConnection (leftDevice );
829- },0 );
830+ },0 );
830831
831832 connectHandler .postDelayed (() -> {
832833 attemptGattConnection (rightDevice );
833- },2000 );
834+ },2000 );
834835 } else {
835836 Log .d (TAG , "Not running a63dd" );
836837 }
@@ -853,7 +854,7 @@ public void connectToSmartGlasses() {
853854 preferredG1DeviceId = getPreferredG1DeviceId (context );
854855
855856 if (!bluetoothAdapter .isEnabled ()) {
856-
857+
857858 return ;
858859 }
859860
@@ -918,15 +919,21 @@ private void attemptGattConnection(BluetoothDevice device) {
918919 connectionState = SmartGlassesConnectionState .CONNECTING ;
919920 connectionEvent (connectionState );
920921
922+ // Connect left first
921923 if (device .getName ().contains ("_L_" ) && leftGlassGatt == null ) {
922924 Log .d (TAG , "Connecting to GATT for Left Glass..." );
923925 leftGlassGatt = device .connectGatt (context , false , leftGattCallback );
924926 isLeftConnected = true ;
925- } else if (device .getName ().contains ("_R_" ) && rightGlassGatt == null ) {
927+ }
928+ // Only connect right after left is fully connected
929+ else if (device .getName ().contains ("_R_" ) && rightGlassGatt == null && isLeftConnected ) {
926930 Log .d (TAG , "Connecting to GATT for Right Glass..." );
927931 rightGlassGatt = device .connectGatt (context , false , rightGattCallback );
928932 isRightConnected = true ;
929933 }
934+ else {
935+ Log .d (TAG , "Waiting for left glass before connecting right" );
936+ }
930937 }
931938
932939 private byte [] createTextPackage (String text , int currentPage , int totalPages , int screenStatus ) {
@@ -1079,17 +1086,30 @@ public synchronized void setFalse() {
10791086 private static final long INITIAL_CONNECTION_DELAY_MS = 350 ; // Adjust this value as needed
10801087
10811088 private void processQueue () {
1089+ Log .d (TAG , "PROC_QUEUE - Starting process queue" );
10821090 //first wait until the services are setup and ready to receive data
10831091 try {
1092+ Log .d (TAG , "PROC_QUEUE - Waiting for left service..." );
10841093 leftServicesWaiter .waitWhileTrue ();
1094+ Log .d (TAG , "PROC_QUEUE - Left service ready" );
1095+
1096+ Log .d (TAG , "PROC_QUEUE - Waiting for right service..." );
10851097 rightServicesWaiter .waitWhileTrue ();
1098+ Log .d (TAG , "PROC_QUEUE - Right service ready" );
1099+
1100+ Log .d (TAG , "PROC_QUEUE - All services ready, starting main queue loop" );
10861101 } catch (InterruptedException e ) {
1087- Log .e (TAG , "Interrupted waiting for descriptor writes: " + e );
1102+ Log .e (TAG , "PROC_QUEUE - Interrupted while waiting for services" , e );
10881103 }
10891104
10901105 while (true ) {
10911106 SendRequest [] requests = sendQueue .poll ();
10921107 if (requests == null ){
1108+ try {
1109+ Thread .sleep (5 );
1110+ } catch (InterruptedException e ) {
1111+ Log .e (TAG , "Error sending data: " + e .getMessage ());
1112+ }
10931113 continue ;
10941114 }
10951115
@@ -1113,23 +1133,29 @@ private void processQueue() {
11131133 if (!request .onlyRight && leftGlassGatt != null && leftTxChar != null && isLeftConnected ) {
11141134 leftWaiter .setTrue ();
11151135 leftTxChar .setValue (request .data );
1136+ leftTxChar .setWriteType (BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT );
11161137 leftSuccess = leftGlassGatt .writeCharacteristic (leftTxChar );
11171138 }
11181139
11191140 if (leftSuccess ) {
11201141 leftWaiter .waitWhileTrue ();
1142+ } else {
1143+ Log .d (TAG , "WRITE FAILED - left" );
11211144 }
11221145
11231146 // Send to right glass
11241147 if (!request .onlyLeft && rightGlassGatt != null && rightTxChar != null && isRightConnected ) {
11251148 rightWaiter .setTrue ();
11261149 rightTxChar .setValue (request .data );
1150+ rightTxChar .setWriteType (BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT );
11271151 rightSuccess = rightGlassGatt .writeCharacteristic (rightTxChar );
11281152 }
11291153
11301154 //wait to make sure the right happens
11311155 if (rightSuccess ) {
11321156 rightWaiter .waitWhileTrue ();
1157+ } else {
1158+ Log .d (TAG , "WRITE FAILED - right" );
11331159 }
11341160 Thread .sleep (DELAY_BETWEEN_CHUNKS_SEND );
11351161
@@ -1630,11 +1656,38 @@ public void sendBrightnessCommand(int brightness, boolean autoLight) {
16301656 EventBus .getDefault ().post (new BrightnessLevelEvent (autoLight ? -1 : brightness ));
16311657 }
16321658
1659+ public void sendHeadUpAngleCommand (int headUpAngle ) {
1660+ // Validate headUpAngle range (0 ~ 60)
1661+ if (headUpAngle < 0 ) {
1662+ headUpAngle = 0 ;
1663+ } else if (headUpAngle > 60 ) {
1664+ headUpAngle = 60 ;
1665+ }
1666+
1667+ // Construct the command
1668+ ByteBuffer buffer = ByteBuffer .allocate (3 );
1669+ buffer .put ((byte ) 0x0B ); // Command for configuring headUp angle
1670+ buffer .put ((byte ) headUpAngle ); // Angle value (0~60)
1671+ buffer .put ((byte ) 0x01 ); // Level (fixed at 0x01)
1672+
1673+ sendDataSequentially (buffer .array (), false );
1674+
1675+ Log .d (TAG , "Sent headUp angle command => Angle: " + headUpAngle );
1676+ EventBus .getDefault ().post (new HeadUpAngleEvent (headUpAngle ));
1677+ }
1678+
16331679 @ Override
16341680 public void updateGlassesBrightness (int brightness ) {
16351681 sendBrightnessCommand (brightness , false );
16361682 }
16371683
1684+ @ Override
1685+ public void updateGlassesHeadUpAngle (int headUpAngle ) {
1686+ sendHeadUpAngleCommand (headUpAngle );
1687+ }
1688+
1689+
1690+
16381691 @ Override
16391692 public void enableGlassesAutoBrightness () {
16401693 sendBrightnessCommand (50 , true );
@@ -2031,39 +2084,10 @@ private void sendChunks(List<byte[]> chunks){
20312084 // Send each chunk with a delay between sends
20322085 for (byte [] chunk : chunks ) {
20332086 sendDataSequentially (chunk );
2034-
2035- // try {
2036- // Thread.sleep(DELAY_BETWEEN_CHUNKS_SEND); // delay between chunks
2037- // } catch (InterruptedException e) {
2038- // e.printStackTrace();
2039- // }
20402087 }
20412088 }
20422089
2043- // public int DEFAULT_CARD_SHOW_TIME = 6;
2044- // public void homeScreenInNSeconds(int n){
2045- // if (n == -1){
2046- // return;
2047- // }
2048- //
2049- // if (n == 0){
2050- // n = DEFAULT_CARD_SHOW_TIME;
2051- // }
2052- //
2053- // //disconnect after slight delay, so our above text gets a chance to show up
2054- // goHomeHandler.removeCallbacksAndMessages(goHomeRunnable);
2055- // goHomeHandler.removeCallbacksAndMessages(null);
2056- // goHomeRunnable = new Runnable() {
2057- // @Override
2058- // public void run() {
2059- // showHomeScreen();
2060- // }};
2061- // goHomeHandler.postDelayed(goHomeRunnable, n * 1000);
2062- // }
2063-
2064-
20652090 //BMP handling
2066-
20672091 // Add these class variables
20682092 private static final int BMP_CHUNK_SIZE = 194 ;
20692093 private static final byte [] GLASSES_ADDRESS = new byte []{0x00 , 0x1c , 0x00 , 0x00 };
@@ -2195,4 +2219,4 @@ private void sendLoremIpsum(){
21952219 String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " ;
21962220 sendDataSequentially (createTextWallChunks (text ));
21972221 }
2198- }
2222+ }
0 commit comments