My Daily Gist | Ferdinand Silva


Print Text On Bluetooth Thermal Printer Using Kotlin

 
package com.ferdinandsilva.printertest2
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothSocket
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.ferdinandsilva.printertest2.ui.theme.PrinterTest2Theme
import java.io.IOException
import java.util.UUID
object PrinterConstants {
const val PRINTER_ADDRESS = "60:6E:41:62:92:F8"
const val PRINTER_SERVICE = "00001101-0000-1000-8000-00805f9b34fb"
}
var btAdapter: BluetoothAdapter? = null
var btDevice: BluetoothDevice? = null
var btSocket: BluetoothSocket? = null
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
btAdapter = bluetoothManager.adapter
btDevice = btAdapter?.getRemoteDevice(PrinterConstants.PRINTER_ADDRESS)
if (btAdapter == null) {
Toast.makeText(applicationContext, "Bluetooth not available", Toast.LENGTH_LONG).show()
} else {
if (btAdapter!!.isEnabled) {
val printerThread = PrinterThread(btDevice!!)
printerThread.start()
}
}
setContent {
PrinterTest2Theme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
PrintButton()
}
}
}
}
@SuppressLint("MissingPermission")
private class PrinterThread(private val device: BluetoothDevice) : Thread() {
private var thisSocket: BluetoothSocket? = null
init {
var tmp: BluetoothSocket? = null
try {
tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(PrinterConstants.PRINTER_SERVICE))
} catch (e: IOException) {
// Handle IOException if needed
}
thisSocket = tmp
}
override fun run() {
btAdapter?.cancelDiscovery()
try {
thisSocket?.connect()
} catch (e: IOException) {
return
}
btSocket = thisSocket!!
}
}
}
@Composable
fun PrintButton() {
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedButton(onClick = {
if (btSocket != null) {
try {
val out = btSocket?.outputStream
out?.write(byteArrayOf(27, 97, 1))
out?.write("This is a test print...\n".toByteArray())
} catch (e: IOException) {
}
}
}) {
Text("Test Print")
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub

Read/write NTFS drive on macOS Ventura with Apple silicon processor

 

Configuring your Mac!

Change security settings

  • Shut down your Mac, then press and hold the power button until "Loading startup options" appear.
  • Select "Options"
  • In the menu on top of the screen, choose "Utilities" -> "Startup Security Utility".
  • Click "Security Policy"
  • Select "Reduced Security" and check "Allow user management of kernel extensions from identified developers".
  • Reboot

Install macFUSE

  • Download latest stable release of macFUSE HERE and install.
  • Allow system extension signed by "Benjamin Fleischer" under "System Settings" -> "Privacy & Security"

Compiling/Installing ntfs-3g

  • Make sure Homebrew is already installed in your system.
  • Install ntfs-3g dependencies
brew install autoconf
brew install automake
brew install libtool
brew install libgcrypt
brew install pkg-config
  • Clone git project then change the current directory to ntfs-3g
git clone https://github.com/tuxera/ntfs-3g.git
cd ntfs-3g 
  • Compile and install
./autogen.sh
./configure --exec-prefix=/usr/local
make
sudo make install

Mounting NTFS drive for reading/writing data

  • After plugging in your NTFS drive, unmount it.
sudo umount /Volumes/LABEL_NAME

LABEL_NAME

  • Identify disk identifier
diskutil list

Example output

  • Mount drive with ntfs-3g
sudo ntfs-3g -o auto_xattr /dev/DISK_IDENTIFIER /Volumes/LABEL_NAME
  • Open the drive using finder and voila!!!!!

Screenshot

view raw ntfs.md hosted with ❤ by GitHub

Linux x86-64 Assembly Language termios Sample Code

 
%define STDIN_FILENO 0
%define TCSAFLUSH 2
%define VMIN 6
%define VTIME 5
%define BRKINT 0x2
%define ICRNL 0x100
%define INPCK 0x10
%define ISTRIP 0x20
%define IXON 0x400
%define OPOST 0x1
%define CS8 0x30
%define ECHO 0x8
%define ICANON 0x2
%define IEXTEN 0x8000
%define ISIG 0x1
%macro get_termios 1
mov rdi, STDIN_FILENO
mov rsi, %1
call tcgetattr
mov rdi, err_tcgetattr
cmp rax, -1
je die
%endmacro
%macro set_termios 1
mov rdi, STDIN_FILENO
mov rsi, TCSAFLUSH
mov rdx, %1
call tcsetattr
mov rdi, err_tcsetattr
cmp rax, -1
je die
%endmacro
%macro print 1
mov rdi, %1
xor rax, rax
call printf
%endmacro
global main
extern printf, perror, tcsetattr, tcgetattr, read, iscntrl
section .data
err_read:
db "read", 0
err_tcsetattr:
db "tcsetattr", 0
err_tcgetattr:
db "tcgetattr", 0
output1:
db "%d", 0xd, 0xa, 0
output2:
db "%d ('%c')", 0xd, 0xa, 0
ctrl_check:
dd 0x1f
intro:
db "Type from your keyboard. Press CTRL + q to exit.", 0xd, 0xa, 0
struc TERMIOS
c_iflag: resd 1
c_oflag: resd 1
c_cflag: resd 1
c_lflag: resd 1
c_cc: resb 255
endstruc
orig_termios: istruc TERMIOS
at c_iflag, dd 0
at c_oflag, dd 0
at c_cflag, dd 0
at c_lflag, dd 0
at c_cc, db ""
iend
raw_termios: istruc TERMIOS
at c_iflag, dd 0
at c_oflag, dd 0
at c_cflag, dd 0
at c_lflag, dd 0
at c_cc, db ""
iend
char_quit:
dd 'q'
section .bss
input_char:
resb 1
section .txt
main:
print intro
get_termios orig_termios
get_termios raw_termios
;enable raw mode
;set c_iflag
mov r15, BRKINT
or r15, ICRNL
or r15, INPCK
or r15, ISTRIP
or r15, IXON
not r15
mov r14, [raw_termios + c_iflag]
and r14, r15
mov [raw_termios + c_iflag], r14
;set c_oflag
mov r15, OPOST
not r15
mov r14, [raw_termios + c_oflag]
and r14, r15
mov [raw_termios + c_oflag], r14
;set c_cflag
mov r15, CS8
mov r14, [raw_termios + c_cflag]
or r14, r15
mov [raw_termios + c_cflag], r14
;set c_lflag
mov r15, ECHO
or r15, ICANON
or r15, IEXTEN
or r15, ISIG
not r15
mov r14, [raw_termios + c_lflag]
and r14, r15
mov [raw_termios + c_lflag], r14
;set VMIN and VTIME
mov r15, raw_termios + c_cc
mov byte [r15 + VMIN], 0
mov byte [r15 + VTIME], 1
mov [raw_termios + c_cc], r15
set_termios raw_termios
;end of enable raw mode
main_loop:
mov [input_char], byte 0
mov rdi, STDIN_FILENO
mov rsi, input_char
mov rdx, 1
call read
mov rdi, err_read
cmp rax, -1
je die
mov rdi, [input_char]
call iscntrl
cmp rax, 0
je isnotctrl
cmp byte [input_char], 0
je ender
mov rsi, [input_char]
print output1
ender:
mov r11, [ctrl_check]
and r11, [char_quit]
cmp r11, [input_char]
je break
jmp main_loop
isnotctrl:
mov rdx, [input_char]
mov rsi, [input_char]
print output2
jmp ender
break:
set_termios orig_termios
mov rdi, 0
jmp exit
die:
call perror
mov rdi, 1
call exit
exit:
mov rax, 0x3c
syscall
ret
view raw test.asm hosted with ❤ by GitHub

Floating Point Operation Sample Code In Assembly Linux x64

 
;floating point operation sample code
;just practicing programming in assembly language (Ferdinand Silva)
global main
extern printf
section .text
main:
call float_operation
mov rdi, str
sub rsp, 8 ;align stack (double is 8 bytes)
mov al, 1 ;count of xmm passed to printf (1 register which is xmm0)
call printf
add rsp, 8 ;cleanup stack
jmp exit
float_operation:
movsd xmm0, [flt]
mulsd xmm0, xmm0 ;multiply flt to itself
ret
exit:
mov rax, 0x3c
mov rdi, 0
syscall
section .data
str: db "The value is: %f", 0xa, 0
flt: dq 6519.765
view raw test.asm hosted with ❤ by GitHub

Titik Programming Language/Interpreter SDL2 Play Sounds

 
if(!(s_i(S_E))) # init sdl
abt('Unable to initialize SDL...')
fi
if(!(s_mi(SM_MP))) # init mix
abt('Unable to initialize SDL Mix...')
fi
if(!(s_moa(SM_D_FR, SM_D_FO, SM_D_CHA, SM_D_CHU))) # open audio
abt('Unable to open audio...')
fi
wav = s_mlw('test.wav')
if(wav == Nil)
abt('Cannot load wav file...')
fi
music = s_mlm('test.mp3')
if(music == Nil)
abt('Cannot load mp3 file...')
fi
s_mpc(wav, -1, 0) #play the wav file once
s_mpm(music, -1) #play the music forever
fl(0, 0)
#nothing to do
lf
s_mfc(wav) #free chunk
s_mfm(music) #free music
s_mca() #close audio
s_mq() #quit mix
s_q() #quit sdl
view raw test.ttk hosted with ❤ by GitHub