2024 Updates

So it is time for me to setup a new development folder. This time around, unlike the many years in the past, all the test projects will be dumped into a testing folder before they are allowed to join any main stream projects that I am working on.

Now with a PC upgrade I am capable of working a lot faster (8 cores/16 threads helps here), especially with running local AI’s and also working in Linux and MacOS. Most of this will be all on the same machine.

Current projects:

  1. Media server and device management software/server.
    • Video playback
    • Image viewer
    • Devices manual updates by client
    • plus many other features…
  2. Godot Game
    • Terrain generator and texture painting
    • Fauna splatting
    • Various generators to add objects in a scene
    • Miscellaneous player controls (ie. sliding down slopes and climbing walls)
  3. Home AI chat on the go.
    • Home AI that runs on a server that allows me to chat over the internet using my phone
    • Text or speech input.
    • Optional text to speech output
    • Selection of local LLM’s (ie Llama chat, or Mistral Instruct)

With WSL in windows it does make it easier to develop and test Linux software, however it is not that good because it doesn’t give raw access to hardware. This is not a problem for development and testing.

There will be a lot more to come over the months as things start to get organised and time is given to these projects.

Catch you all soon…

Carl

ChatGPT vs Google Bard: AI programming in C++

Bard fails miserably at recursive programming where ChatGPT gave an almost finished result.

I asked both to write a C++ program given a folder to monitor its contents and recurs down through all sub folders and monitor those files too.

At the moment, Bard hasn’t got a grip on recursive programming. ChatGPT came out the clear winner. Although I did have to coax it to get it to include the right header files.

The final result definitely wouldn’t be production worthy but a good start to show how to work on this particular task type.

#include <iostream>
#include <sys/inotify.h>
#include <unistd.h>
#include <cstring>
#include <vector>
#include <dirent.h>

#define EVENT_SIZE (sizeof(struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))

void monitorDirectory(const char* directory, int fd, std::vector<int>& watchDescriptors) {
    // Add a watch for the specified directory
    int wd = inotify_add_watch(fd, directory, IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO);
    if (wd < 0) {
        std::cerr << "Failed to add watch for directory: " << directory << std::endl;
        return;
    }

    watchDescriptors.push_back(wd);

    // Scan subdirectories
    DIR* dir = opendir(directory);
    if (!dir) {
        std::cerr << "Failed to open directory: " << directory << std::endl;
        return;
    }

    struct dirent* entry;
    while ((entry = readdir(dir)) != nullptr) {
        if (entry->d_type == DT_DIR) {
            if (std::strcmp(entry->d_name, ".") != 0 && std::strcmp(entry->d_name, "..") != 0) {
                std::string subdirectory = std::string(directory) + "/" + entry->d_name;
                monitorDirectory(subdirectory.c_str(), fd, watchDescriptors);
            }
        }
    }

    closedir(dir);
}

int main() {
    int fd = inotify_init();
    if (fd < 0) {
        std::cerr << "Failed to initialize inotify" << std::endl;
        return 1;
    }

    const char* directory = "/home/wlgfx/Downloads";
    std::vector<int> watchDescriptors;
    monitorDirectory(directory, fd, watchDescriptors);

    std::cout << "Monitoring changes in directory: " << directory << std::endl;

    char buffer[EVENT_BUF_LEN];
    while (true) {
        int length = read(fd, buffer, EVENT_BUF_LEN);
        if (length < 0) {
            std::cerr << "Failed to read events" << std::endl;
            break;
        }

        int i = 0;
        while (i < length) {
            struct inotify_event* event = (struct inotify_event*)&buffer[i];
            if (event->len) {
                if (event->mask & IN_CREATE)
                    std::cout << "File created: " << event->name << std::endl;
                else if (event->mask & IN_DELETE)
                    std::cout << "File deleted: " << event->name << std::endl;
                else if (event->mask & IN_MODIFY)
                    std::cout << "File modified: " << event->name << std::endl;
                else if (event->mask & IN_MOVED_FROM)
                    std::cout << "File/Folder moved from: " << event->name << std::endl;
                else if (event->mask & IN_MOVED_TO)
                    std::cout << "File/Folder moved to: " << event->name << std::endl;
            }
            i += EVENT_SIZE + event->len;
        }
    }

    // Cleanup
    for (int wd : watchDescriptors)
        inotify_rm_watch(fd, wd);

    close(fd);

    return 0;
}

Server bully test

Well, not exactly crashed the server, but I stopped it from running which is a proof of concept.

With a simple Java program which sends legitimate requests from a legitimate device, the server failed after a few minutes. A quick manual restart over ssh got it up and running immediately.

public class BullyServerTest {
    
    public static BullyServerTest bst;

    public static void main(String[] args) {
        bst = new BullyServerTest();
    }
    
    boolean quit = false;
    
    private final String server_host = "SOMEWEBADDRESS"; // LOL
    private final int server_port = SOMESECRETNUMBER;
    
    private final String home = System.getProperty("user.home") + "/";
    
    public BullyServerTest() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                quit = true;
                try { Thread.sleep(1000); } catch (InterruptedException ex) {}
            }
        });
        
        while (!quit) {
            try { Thread.sleep(randInt(10, 250)); } catch (InterruptedException ex) {}
            do_hello_world_bully();
        }
    }
    
    Random rand = new Random();
    
    private int randInt(int min, int max) {
        return rand.nextInt((max - min) + 1) + min;
    }
    
    private static final int COMMAND_HELLO = 1234;
    
    private void do_hello_world_bully() {
        int count = randInt(10, 100);
        System.out.println("HELLO WORLD BULLY at " + count + " times");
        
        while (count-- != 0) { // a shed load of threads at once
            new Thread(runnable_HW).start();
        }
        
        System.out.println("Completed...");
    }
    
    Runnable runnable_HW = new Runnable() {
        @Override
        public void run() {
            try {
                WLSocket socket = new WLSocket(server_host, server_port);

                socket.out.writeInt(COMMAND_HELLO);
                String hello = socket.in.readUTF();
                
            } catch (IOException ex) {
                System.out.println("Server failed with HELLO WORLD response");
            }
        }
    };
}

So the next step is to implement a thread pool so that the server will not hang on too many requests. It ran for less than a minute. The above program kept running until my 12Gb RAM ran out which was a bit longer. The current server does only have 4Gb RAM and couldn’t handle the amount of connections at once. I’ve also had to keep the sudden bandwidth usage down as I was hitting my upload and download limits.

Eventually the server and client code will all be rewritten in C++ and handle such things as low latency timeouts.

This has been a very interesting test. I’ll be leaving the hello world server command in for future testing to simulate fake requests.

Start menu dissappeared on Linux Mint 18.1

So, as I boot up ready to get some important emails out tonight, I found my start menu had disappeared. The bottom panel was there but no menu.

I did find that I could add start menus from the panel options, something you can’t do in Windows, but still with the three that were available, one didn’t work. And I couldn’t put it back to where it should go, in the bottom left of the panel.

I found some help: Linux Mint forums

All I needed to do was to open a terminal window, CTRL + ALT + T and enter the following:

mate-panel --reset

mintmenu --reset

And all is well again.

Thinking about it though, it might be time to reinstall Linux possibly to Ubuntu Mate. I’ll think about it at the weekend.

Linux Thunar file manager

With all the faffing about lately with assembler at home, I remembered how easy things were when I had my Amiga 1200. On the Amiga, I used to use Directory Opus which allowed me to customise such things as compiling assembler and C files.

Image result for amiga directory opus

All those empty boxes could be custom build commands, archiving, running my own scipts, etc. Even the ones that are in the screen shot could be removed and changed for something else which I did at the time. Creating software using Directory Opus was a doddle.

I needed something exactly like those old days now. Actually I should’ve looked for this a long time ago.

I found Thunar file manager. I’ve just tested it out with a simple GCC compiling a C program and making an executable. How simple it was makes this awesome.

Image result for thunar file manager custom commands

I’m hoping I can add my custom commands to keyboard shortcuts and also group them. Apart from that it looks just like any other file manager. All I need to do is to right click or do a keyboard shortcut and any of my custom actions can be done instantly. This will make life so much easier from now on.

eg… Compile a C/C++ program and create an executable:

Eclipse Oxygen and NASM

Tonight I set myself a mission of getting any IDE to build assembler files alongside my C/C++ code.

Find it here: Eclipse Oxygen and NASM

I tried NetBeans at first but the IDE isn’t good at all, actually quite useless for setting up NASM. I spent about half an hour trying this out and eventually gave up. Apparently there are plugins out there, but I wasn’t going to try them out as they were not part of the NetBeans official plugins.

So I look into Eclipse and initially I was put off because there was nothing in the official plugins. A few searches later and I got it. It was already built in to the CDT plugin for eclipse. I only had to make a minor alteration to get it working.

Now I can have a C/C++ project that will also automatically compile and link my assembler source files.

Here’s me thinking I was going to be stuck over the weekend finding this out. Took an hour. What’s next to move on to? Oh yeah, my project. he he…

Assembler PRNG (from Java to Asm)

So, I had a perfectly working PRNG in Java like this:

public class WLPRNG {
    
    long seed;
    
    public WLPRNG(long seed) { this.seed = seed; }
    
    public int nextInt() {
        long result = seed + 0x123defca;
        result = Long.rotateLeft(result, 19);
        result += 0xbead6789;
        result *= 0x1234567c;
        
        int temp = (int)result;
        
        result ^= 0x5ecdab73;
        result = Long.rotateLeft(result, 48);
        
        if (temp % 4 == 0) result *= 0x87650027;
        
        result += 13;
        seed = result;
        
        return (int)result;
    }

    public byte nextByte() {
        return (byte)nextInt();
    }
}

And I thought I’d test out the Assembler version like this:

; random number generator to be used in crypto transmission
; of sensitive data over the internet

; WLGfx 2017-Nov-19

        section .text

global  main

extern  printf

srand:  mov     [seed],rax                      ; set random seed
        ret

arand:  mov     rax,[seed]                      ; get seed
        mov     rbx,qword 0x023defca321acfed
        add     rax,rbx                         ; add 64 bit value
        rol     rax,19                          ; rotate bits
        mov     rbx,qword 0xbead6789
        add     rax,rbx                         ; another add
        imul    rax,qword 0x1234567c            ; a multiple this time
        mov     rbx,rax                         ; copy into rbx
        xor     rax,qword 0x5ecdab73            ; flip some bits
        rol     rax,48                          ; rotate bits again
        mov     rcx,rax                         ; copy to rcx
        and     rax,0x3                         ; mask and test with 0
        jnz     .notz                           ; 25% chance of other ops
        mov     rax,rbx
        add     rcx,rax
        mov     rbx,qword 0x87650027
        imul    rax,rbx
        jmp     .cont
.notz   mov     rax,rcx                         ; back into rax
.cont   mov     [seed],rax                      ; store into seed
        and     rax,0xff                        ; return byte value only
        ret

main:   mov     rax,9                           ; set seed
        call    srand

        mov     dword[lc],10                    ; set loop counter

.loop   call    arand                           ; get random byte

        push    rbp                             ; stack frame
        mov     rsi,rax                         ; random number
        mov     rdi,pf_msg                      ; format string
        xor     rax,rax                         ; 0
        call    printf                          ; call printf
        pop     rbp                             ; stack frame

        sub     dword[lc],1                     ; dec loop counter
        jnz     .loop
        
        ret

        section .data

seed    dq      0,0,0,0                         ; random seed value 64 bit
lc      dd      10                              ; loop counter

pf_msg  db      "Number: 0x%02x",10,0

Using the build script:

#!/bin/bash
nasm -f elf64 random.asm
gcc -o random random.o

Gives a sample output of:

 ~/dev/asm/tests $ ./buildrand.sh 
 ~/dev/asm/tests $ ./random 
Number: 0xe0
Number: 0x5b
Number: 0xca
Number: 0x7c
Number: 0xfc
Number: 0x2d
Number: 0x79
Number: 0xa5
Number: 0x62
Number: 0x7f

All I need to do now is to be able to link directly to C and C++ code. I’m currently reading up on threading in assembler, but it looks like the standard pthreads are just the same really.

There’s lot’s of potential for using assembler.

X86_64 printf 64 bit assembler test

So, I wanted to start playing about with assembler again. Mainly so I could use it for data encryption over the internet. Here’s a simple sample of printing 64 bit numbers as hex.

section .text
global  main

extern  printf

; use printf to print 64 bit hex string

_test:  push    rbp

        mov     rsi,0x1234567890abcdef
        mov     rdi,pf_msg
        xor     rax,rax
        call    printf

        pop     rbp
        
        ret

main:   call    _test
        
        mov     edx,len
        mov     ecx,msg
        mov     eax,4
        int     128
        
        ;mov     eax,1
        ;int     128
        
        xor     rax,rax
        ret

section .data

msg     db      "Hello world!",10
len     equ     $ - msg

; some testing stuff

pf_msg  db      "Register = %016llx", 10, 0

I set up a simple script to build the executable.

#!/bin/bash
nasm -f elf64 test.asm
gcc -o test test.o

And the output is just…

Register = 1234567890abcdef
Hello world!

Linux shell scripts

Another thing I’ve been playing about with for the last couple of weeks is automating stuff using shell scripting.

Wow! How much time can it save you by just writing a simple script.

There’s been loads of times when I wanted to backup my project. Not only can a small script do that but it can also rename and older backup file to something else as well. By just dropping a script into a directory and run it, I’m now capable of personal version control. Okay not quite the same thing, but I know what I mean.

I’m on the verge of now being able to run scripts to automatically update software on a remote machine too using ssl. So far I can package up various pieces of software (build them if needed too) and use the scp┬ácommand to copy them to a remote machine. All I need to do next is to be able to run commands and scripts over ssl. Almost there.

This shell scripting is amazingly powerful.

A day spent programming

Yep, a day of blitzing code.

There’s a total of four pieces of software I’m writing for this project. The server. The media manager. The device manager. And the device player. All four of them are now well on the way to being tested out soon enough.

So far the server works flawlessly with the media manager which can run on any OS, ie Linux, Windows or Mac.

The player is for embedded Linux only and also has some in built security layers.

The device manager runs on Android which makes it so much easier when setting up the devices.

The next step is to get the device player software to handle communication with the server and retrieve its playlist and it’s all ready for the big demo.

Once the demo setup has been produced I can move on to adding all the security layers in which will include encrypted communications over the internet.