Wednesday, May 17, 2017

Setting Up RTSP Server in Raspberry PI and Zoneminder

I have been testing at Raspberry PI Zero W as a security camera connected to ZoneMinder for few weeks and it has been working perfectly. No drop frames or delays or cables or dongles or anything. Just a Pi Zero W, Camera Module and Power Supply.

I used the following links as reference:

Prepare Raspberry PI SD Card with Raspbian Jessie Lite:

dd bs=4M if=Desktop/2017-04-10-raspbian-jessie-lite.img of=/dev/sdX


Setup Raspberry PI:

  • sudo apt-get update
  • sudo apt-get upgrade
  • sudo raspi-config
    • Change Hostname to something meaningful
    • Localisation Options -> Change Locale
    • Localisation Options -> Change Timezone
      • Interfacing Options -> P1 Camera to Enable
      • Interfacing Options -> P2 SSH (optional)
      • Advance Options -> A1 Expand Filesystem
      • Advance Options -> Memory Split (128M or 256M)
    • Set WIFI
    sudo iwlist wlan0 scan (optional just to scan)
    sudo wpa_passphrase "YOUR_SSID" "YOUR_PASSWORD" >> /etc/wpa_supplicant/wpa_supplicant.conf

      • Delete plain text password entry from wpa_supplicant.conf  (optional)
    sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
    • Add Camera module to list of modules to start at boot
    sudo echo "bcm2835-v4l2" >>  /etc/modules-load.d/picamera.conf

    Install Dependencies:

    sudo apt-get install git cmake
    wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz -O - | tar xvzf -
    cd live
    ./genMakefiles linux
    sudo make CPPFLAGS=-DALLOW_RTSP_SERVER_PORT_REUSE=1 install

    Install v4l2rtspserver:

    git clone https://github.com/mpromonet/v4l2rtspserver
    cd v4l2rtspserver
    cmake .
    make
    sudo make install


    Systemd Startup Script (Thank you Andrew):

    In order to get v4l2rtspserver to start automatically after boot, I created a systemd service file. Create the file /etc/systemd/system/v4l2rtspserver.service and add the following contents. Adjust i_frame_period and -F to the frame rate that you want to record.

    # systemd configuration for v4l2rtspserver
    # /etc/systemd/system/v4l2rtspserver.service
    [Unit]
    Description=v4l2rtspserver rtsp streaming server
    After=network.target
    [Service]
    #ExecStartPre=/usr/bin/v4l2-ctl --set-ctrl vertical_flip=1
    #ExecStartPre=/usr/bin/v4l2-ctl --set-ctrl rotate=90
    ExecStartPre=/usr/bin/v4l2-ctl --set-ctrl h264_i_frame_period=4
    ExecStart=/usr/local/bin/v4l2rtspserver -F 4 -W 1920 -H 1080
    #ExecReload=/bin/kill -HUP $MAINPID
    Type=simple
    User=root
    Group=video
    Restart=always
    [Install]
    WantedBy=multi-user.target

    Let's give it a try:

    sudo systemctl enable v4l2rtspserver
    sudo systemctl start v4l2rtspserver


    ZoneMinder Configuration:

    • Source Type: Remote
    • Remote Protocol: RTSP
    • Remote Method: RTP/Unicast
    • Remote Host Name: Hostname or IP
    • Remote Host Port: 8554
    • Remote Host Path: /unicast
    • Capture Width: 1920
    • Capture Height: 1080




    Monday, August 12, 2013

    Another Simple sha256 Proof of work

    This is a very simple implementation of a proof of work for Python 3. The idea is to encode a string in sha256 and look for a token that will make the string+token to start with a given number of zeros.

    It is based on this link: simple-hashcash-implementation

    The main difference is that this code create trailing zeros and sha1while my use leading zeros and sha256.


    import math, itertools
    from hashlib import *


    def lz(n):
    # Number of leading 0s in binary representation of integer n.
        if n <=0 : return 0

    #   string with binary representation
        b = bin(n)[2:].zfill(256)

        i = 0
        for c in b:
    #       print(c)
            if c == '0':
                i = i + 1
            else:
                break
        return i

    def irange(n):
    # Implementation of xrange(n) that does not overflow.
        i = 0
        while i < n:
            yield i; i += 1

    def all_strings(charset='0123456789abcdef'):
    # Yields all strings in given character set, sorted by length.
        m = len(charset)   
        for n in itertools.count(0):
            for i in irange(m**n):
                yield ''.join([charset[(i//(m**j))%m] for j in range(n)])


    def hash(s_to_hash):
    # Hash function used by hashcash. Returns an integer.
        s = s_to_hash.encode('utf-8')
        return int(sha256(s).hexdigest(), 16)

    def mt(s_to_hash, n, charset='0123456789abcdef'):
    # Makes hashcash token of value 'n' against basestring 's'.
        s = s_to_hash.encode('utf-8')
        h = sha256(s).hexdigest()
        for token in all_strings(charset):
            if lz(hash(h + token)) >= n: return token

    def vt(s_to_hash, token):
    # Returns hashcash value of given token against basestring 's'.

        s = (s_to_hash).encode('utf-8')
        return lz(hash(sha256(s).hexdigest() + token))
    #

    def Example():

        StringToConvert = input("Enter a string: ")
        MinLeadingZeros = int(input("Leading Zeros required: "))

        csha = StringToConvert.encode('utf-8')
        c_hex = sha256(csha).hexdigest()
        print("String sha256 (hex encoded): " + c_hex + "\n")
       
        c_bin = bin(int(c_hex, 16))[2:].zfill(256)
        print("String sha256 (bin encoded): " + c_bin + "\n")

        token = mt(StringToConvert,MinLeadingZeros)
        print("Token for this sha256: " + token)

        c_t = (c_hex + token).encode('utf-8')
        print("String + token (hex encoded): " + c_hex + token + "\n")

        c_t_hex = sha256(c_t).hexdigest()
        print("String + token sha256 (hex encoded): " + c_t_hex + "\n")

        c_t_bin = bin(int(c_t_hex, 16))[2:].zfill(256)
        print("String + token (bin encoded): " + c_t_bin + "\n")

        print("Verify Token")

        l_z = vt(StringToConvert,token)
        print("Verified Leading Zeros: " + str(l_z) + "\n")
       

    def GetToken():
        StringToConvert = input("Enter a string: ")
        MinLeadingZeros = int(input("Leading Zeros required: "))

        StringToken = mt(StringToConvert, MinLeadingZeros)
        print(StringToken)

    def VerifyToken():
        StringToVerify = input("Enter a string: ")
        TokenToVerify = input("Enter a Token: ")

        LeadingZeros = vt(StringToVerify, TokenToVerify)
        print(LeadingZeros)
       

    Thursday, January 31, 2013

    Simple Python Encryption and Decryption

    The following is a just an example of how to encrypt and decrypt a message with Python Crypto. It could be simple but took me some time to learn how to do it.

    -------------------------- encrypt.py -------------------------------
    #!/usr/bin/python

    from Crypto.Cipher import AES
    from Crypto import Random
    import hashlib

    # This is the password to be used
    password = raw_input("Enter password: ")

    # This create a 256 bit hash from the password.
    key = hashlib.sha256(password).digest()

    # Plain text to be encrypted
    plaintext = raw_input("Enter Message: ")

    # create a random iv.
    iv = Random.new().read(AES.block_size)

    # Create a aes object.
    encobj = AES.new(key, AES.MODE_CFB, iv)

    # String with iv and encrypted message
    ciphertext = iv + encobj.encrypt(plaintext)

    # Resulting ciphertext in hex
    # Print hex because is cleaner in the terminal screen.
    print ciphertext.encode('hex')

    ------------------------ decrypt.py ----------------------------------------

    #!/usr/bin/python

    from Crypto.Cipher import AES
    from Crypto import Random
    import hashlib

    # Password to be used
    password = raw_input("Enter password: ")

    # Create a 256 bit hash from the password
    key = hashlib.sha256(password).digest()

    # Encoded message to be decrypted
    cipher_msg = raw_input("Enter Cipher: ").decode('hex')

    # Get iv from the first 16 charecter in the message
    iv = cipher_msg[:16]
    # Get the message to be decrypted
    cipher = cipher_msg[16:]

    # Create the AES object
    encobj = AES.new(key, AES.MODE_CFB, iv)

    # Decrypt the message
    plaintext = encobj.decrypt(cipher)

    print plaintext

    Sunday, October 28, 2012

    How to Compile RaspberryPI Kernel

    The actual process of compiling Linux Kernel is not really difficult, and it has been documented in hundreds of websites and blogs. However since the raspberrypi cpu's is not really too fast it can take many hours to compile the kernel native in the raspberrypi. Then is essential to setup another computer to perform cross compilation and be able to copy the Image and modules files.

    I found two great tutorials here and here, which guide me in the right direction. Since there are many different ways to achieve the same goal. I will documents the steps that worked for me.

    In your Linux Desktop

    1) First install Git if you don't have it already.
    $ sudo apt-get install git

    2) Install packages required to cross compilation
    $ sudo apt-get install git gcc-arm-linux-gnueabi make ncurses-dev

    3) Create a directory to download raspbian kernel in your home directory.

    $ cd ~/
    $ mkdir raspberrypi
    $ cd raspberrypi$ git clone https://github.com/raspberrypi/firmware
    $ git clone git://github.com/raspberrypi/linux.git

     -- or to download just the latest --

    $ git clone --depth 1 git://github.com/raspberrypi/linux.git $ cd linux

    4) Configure kernel
    Option 1: Obtain the .config from your existing Raspberrypi Kernel
    $ sudo zcat /proc/config.gz > .config

    Then, copy this file to your desktop computer raspberrypi/linux directory with scp or by any other way.

    Option 2: Use the standard broadcom raspberrypi cutdown .config file.
    $ cp arch/arm/configs/bcmrpi_cutdown_defconfig .config
    Once you have .config file perform a "oldconfig" this will create a new .config based in the old .config file but with options and selections according to the new kernel file.

    $ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig
    This will ask you a thousand questions, just press Enter to accept the default configuration. You would be able to make changes in the next step.

    Optional - But probably the only good reason to recompile the kernel. Add or modify kernel options and settings.
    $ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig

    5) Compile kernel
    $ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k
    In you have a multicore processor use the "-j" argument with a number between 1.5 or twice the number of cpu's in your computer.
    ej. in my AMD 4 cores I use the following. It just takes around 5 minutes to compile.
     $ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k -j 6

    In your Raspberry PI.

    Copy your files to a RaspberryPI. We have many ways to do this, I will describe my favorite.

    6) Boot your raspberry - easy !

    7) Install sshfs in your RPI, also you must have ssh or openssh-server for debian distros installed and running in your desktop.
     $ sudo apt-get install sshfs

    8) Install Modules in your RaspberryPI

    $ cd /mnt
    $ mkdir raspbian
    $ sshfs user@host:raspberrypi raspbian
    $ cd raspbian/linux
    $ sudo make modules_install

    9) Copy new firmware
    $ cd /mnt/raspbian/firmware/boot
    $  cp * /boot

    10) Copy yout custom kernel from Desktop to PI
    $ sudo cp arch/arm/boot/Image /boot/kernel.img
    11) Edit /boot/config.txt and add your memory split settings
    gpu_mem_256=64
    gpu_mem_512=128

    12) Reboot



    Sunday, July 17, 2011

    Simple Step by Step Sheeva plugcomputer upgrade

    After a long time running my sheevaplug with the original Ubuntu 9.04 the last Ubuntu version available for the sheeva, I found myself without any security update, no APT no nothing. I have stretched this non LTS Ubuntu version to the maximum.

    Since the actual update took me a long long time, due to a series of technical problems and the difficulty of getting the uboot bin file, I will document every single step and will include a link to every file to make sure that I can refresh my sheeva easily in the future. There are many other how-to's around the web, I tried few of them but non worked for me.

    Pre-Requisites:
    • A 32b linux installation
    • php5-cli
    • openocd
    • libftdi1
    • Sheeva Plug Installer (a 145MB download link)
    Just get a old pc/laptop with a 32b linux, I'm using LinuxMint but any other distro should work fine, also VirtualBox should work but I haven't tried yet.
    Install php5-cli if you don't have it installed.
    sudo apt-get install php5-cli
    I had problems running the php script because the default configuration didn't included the local environmental variables. So take a look to:

    /etc/php5/cli/php.ini

    search for "variables_order"
    and make sure the E is there; like that:
    variables_order = "EGPCS"
    install openocd;

    sudo apt-get install openocd
    Then install libftdi1

    sudo apt-get install libftdi1

    And to finish the prep work, download and extract the Sheeva Plug Installer to your favorite directory.

    Setup you connection
    These are the setting to connect to your sheeva plug with any terminal from link.
    • 115200 baud
    • 8 data bit
    • N parity
    • 1 stop byte
    • 0 (none) flow control
    Connect the Sheeva, reboot and launch putty or you favorite terminal, you should see booting process. You have few second to interrupt the booting process and go directly to uboot; confirm the uboot version with.
    uboot version
    The Sheeva Plug installer includes uboot version 3.4.19. Others howto's recommend U-Boot 3.4.27+pingtoo.

    U-Boot Upgrade

    Took me a while to get the bin file, but I finally found it in here. The actual uboot is part of the zip file in "Preparing USB Pendrive". By the way this is great tutorial. Or you can download the U-Boot 3.4.27+pingtoo from here.

    Replace the uboot.bin file in /sheevaplug-installer/uboot with this uboot.bin. Edit /sheevaplug-installer/uboot/uboot-env/uboot-nand-custom.txt to include your sheeva plug MAC address.


    Prepare the USB drive

    Download and save the following files in a formatted USB drive.
    • initrd (this is the same found in the installer)
    • uImage kernel 2.6.39.3 (or newer from http://sheeva.with-linux.com/sheeva/ )
    • modules.tar.gz 2.6.39.3 (or newer from http://sheeva.with-linux.com/sheeva/ )
    • rootfs.tar.gz (or make your own with this script, download to your current sheeva, chmod +x and run as root)
    Upgrade

    Plug the USB drive in the sheeva, and run the following command from the sheevaplug-installer folder.
    php runme.php nand
    This should copy the new uboot into the sheeva, and then will execute run recover1. If you just want to reflash withou upgrade uboot, just execute run recover1 from the uboot console.

    Finishing

    1. check the date, apt-get may not work if the date is wrong.
    2. apt-get update
    3. apt-get upgrade
    4. regenerate the ssh
      • rm /etc/ssh/ssh_host*
      • ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ""
      • ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""
    5. dpkg-reconfigure tzdata
    6. dpkg-reconfigure locales
    7. edit /etc/hostname to change the hostname.
    Credits
    http://www.plugcomputer.org/downloads/plug-basic/

    Since the original link from plugcomputer forum is broken, I used the uboot found here: http://caller9.com/blog/21/full/

    Manually unpacking a tar ball of Debian on SheevaPlug
    http://www.cyrius.com/debian/kirkwood/sheevaplug/unpack.html

    SheevaPlug Installer
    http://plugcomputer.org/plugwiki/index.php/SheevaPlug_Installer

    U-Boot Links:

    Uboot howto Cross Compile
    http://doukki.net/wiki/tutoriels/uboot.howto

    Upgrading SheevaPlug's Uboot
    http://www.cyrius.com/debian/kirkwood/sheevaplug/uboot-upgrade.html

    Saturday, June 18, 2011

    AWS Adventures

    These are my first three steps to create a Ubuntu instance in Amazon EC2.

    1) Ubuntu Official AMI's are published by user with Amazon ID '099720109477'.

    after the instance get launched you can access the instance with the public DNS and the AWS pem file.

    2) ssh -i awskey.pem ubuntu@ec2-01-02-03-04.compute-1.amazonaws.com

    To facilitate ssh, i prefer to send my own key to the instance with ssh-copy-id. Here is the link to create your own key pair.

    3)cat id_rsa.pub | ssh -i testkey.pem ubuntu@ec2-01-02-03-04.compute-1.amazonaws.com "cat>> .ssh/authorized_keys"

    At this point my instance is ready, and easily accessible with my own rsa credentials.

    Saturday, February 20, 2010

    These are the instructions to compile transmission in a sheevaplug. From elBradford. http://bradford.law-family.org/success-building-transmission-1-80-from-source-on-sheevaplug/ This link was down on February 20, 2010. I get access to it from google cache.

    1) I think the last 3 package are not really required, for a non gtk installation
    # apt-get install build-essential automake autoconf libtool pkg-config
    libcurl4-openssl-dev intltool libxml2-dev libgtk2.0-dev libnotify-dev libglib2.0-dev
    * now libevent-dev is required, a had to download it and compile it.

    2) Download the latest transmission from:

    http://download.m0k.org/transmission/files/


    # wget "and the actual link to the latest file"

    3) Extract the files

    # tar –xvf transmission-1.90.tar.bz2

    4) Enter in directory and:

    # ./configure –-disable-gtk --disable-cli

    5) First Backup your current settings.json and purge current installed torrent.
    # aptitude purge transmission-daemon

    5) Build

    # make

    # make install

    6) Setup init scrip as per this link.

    7) edit init script transmission-home to point /etc/transmission instead of default /root/.conf/transmission

    Create transmission user: adduser Make sure transmission user has access is the owner of the directory.

    8) Configure /etc/transmission/settings.json

    9) start transmission

    # /etc/init.d/transmission-daemon start


    10) Add rc links

    #update-rc.d transmission-daemon defaults