Tuesday, February 18, 2014

Full C++ Socket Server on Linux

There are many examples online as to how to construct one's own client / server socket connection in C++, but unfortunately they do kind of take for granted that you know your stuff. Here I will share my working source code which satisfied the questions I asked but could not find:

For this, I used Linux Mint 16 in VirtualBox with a Bridged Network Connection (my virtual machine had it's own IP address assigned by the local network router). Also used a C/C++ Eclipse IDE and the GCC Compiler, here is my server code: (the client side that tested this is in C# on the host OS, Windows 7)

#include <iostream>     // time, ctime
#include <cstdlib>      // exit
#include <cstdio>       // snprintf
#include <unistd.h>     // gethostname, write, close, sleep
#include <netdb.h>      // socket, htonl, htons
#define MAXHOSTNAME 256
void* memset(void* b, int c, size_t len);

int main()
{
  int listenfd = 0, connfd = 0, n;
  struct sockaddr_in serv_addr;
  const int BUFF = 32;
  char ioBuff[BUFF];

  // create socket and flush memory blocks

  listenfd = socket(AF_INET, SOCK_STREAM, 0);
  memset(&serv_addr, '0', sizeof(serv_addr));
  memset(ioBuff, '0', sizeof(ioBuff));

  // set socket properties

  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 0.0.0.0
  serv_addr.sin_port = htons(8080);

  // Initialize and start the socket

  bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
  listen(listenfd, 10);

  while(1)

  {
    // receive incoming connection
    connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);

     do

     {
        // read data from client
        n = read(connfd, ioBuff, BUFF);
        ioBuff[BUFF-1] = (char)NULL; // terminate string
        std::cout << n << ": " << ioBuff;

        // write data to client

        write(connfd, ioBuff, BUFF);

            // continue to read and write until '-1' is received

     }while((int8_t)ioBuff[0] != -1);

     // close connection and repeat

     close(connfd);
     sleep(1);
  }
}

void* memset(void* b, int c, size_t len) {

    char* p = (char*)b;
    for (size_t i = 0; i != len; ++i) {
        p[i] = c;
    }
    return b;
}

For a full C++ server and client example, see this post on www.thegeekstuff.com.



Back Story
As part of the same project mentioned in my earlier post, GPIO, BeagleBone, and Bash, the next challenge was to communicate with the device over a network. The first choice that came to mind was the secure shell (SSH). I needed to communicate programmatically using my language of choice, C#.

I found SSH.NET and put something simple together. As excited as I may have been for a successful connection, I was now facing some serious LAG! (You know, the same lag everyone notices when playing Super Smash Bros. Brawl world wide?) It is time for alternatives!

C# doesn't exactly have many good SSH libraries out there for some odd reason. One of those weird outcomes of Microsoft. Nevertheless, all is not lost... I could still do this in C++ and then write a wrapper around that in C#. Success! Using libssh, a free open-source C++ library, I am sending SSH commands much more quickly.

(I need to use C# because I have a library written only in C# - no other language. Though I do now have the source code and could port it, this task would prove time consuming considering several hundred lines of code and then would need debugging and testing letter on - maybe better for a future project)

Just about finished here, several friends point out, using SSH for what I'm trying to accomplish is overkill! Since I am not sending commands through the global network but a local one, I should not need these layers of security. Instead, I should construct a simple socket connection. Benefits: I can get an even faster speed-boost, and I can write the socket client in C# while the socket server is all in C++!

With my trial run, as of today (Feb 18, 2014), I am very pleased with the results!

Friday, February 14, 2014

GPIO, BeagleBone, and Bash

As the AUVSI competing team electrical engineer at Utah State University, I have been tasked with the effort to turn our skeletal structure into an ROV (Remotely Operated underwater Vehicle) or in other words, an RC Sub. Well, volunteered, as a chance to get my hands messy with a few new electrical component: BeagleBone Black, Wii Classic Controller, and a few 14" VideoRay Thrusters w/Castle Creations ESCs! (If ever you want good experience and to learn new things outside of school, team-up and enter one of several special annual AUVSI competitions!)

Aside from the small story above, here is the real stuff I'd like to share for the benefit of all developers out there...

The task: Make an RC submarine
User input: Wii Classic Controller
RC Feedback: VideoRay Thruster Control
User-RC Linking: Wireless/WiFi

GPIO Pins!
The main challenge I encountered here is sending commands to the beaglebone and getting a pinout reaction from it. Arduino has the 'Serial' libraries but I'm not sure for the beaglebone. (It has been a bit of a challenge to find what I want exactly through Google.) Perhaps there is something, but for now, I found another way: my favorite Linux feature! The Bash/Shell Terminal!

Since Linux is a big fan of files, one doesn't need to go and write drivers to read and write IO data. With that said, one can simply read from or write to a GPIO pin just as they would any other file!

By default, GPIO 'files' have not been created yet and therefore need to be.
This can be done as follows:
# this will create the file for GPIO_30
# (Pin 11 on the P9 header)
echo 30 > /sys/class/gpio/export

Here is a pinout diagram of the BeagleBone Black:

Now to set the bin as an input or an output pin:
echo out > /sys/class/gpio/gpio30/direction # for output
echo in > /sys/class/gpio/gpio30/direction # for input
# NOTE: you can also set the pin to output
# and high or low at the same time by using
# 'high' or 'low' in place of 'out.'

To write to a pin, type the following shell command:
echo 1 > /sys/class/gpio/gpio30/value
# this will set GPIO_30 to high; 0 is for low

To read from a pin, type the following:
cat /sys/class/gpio/gpio30/value
# this will echo the current bit value of the wire


PWM Pins!
I spent a bit of time messing around with general purpose IO pins controlling my BBB with a Wiimote. Again, the overall objective is to control an AUV with the wiimote extensions. (Check out my socket server source code here. Simply use the system("") and a switch to run commands. For the wiimote part, I used a revised version of the wiimotelib library online as well as the C# client socket example from MSDN)

To get started with PWM output, we need to set up the environment:
echo am33xx_pwm > /sys/devices/bone_capemgr.9/slots

Next, to assign a pin: (these lines will assign pins P8_13 and P9_14 respectively)
echo bone_pwm_P8_13 > /sys/devices/bone_capemgr.9/slots
echo bone_pwm_P9_14 > /sys/devices/bone_capemgr.9/slots

Set the period and duty for each pin:
# so  20000000 = 0.02 seconds
echo 20000000 > /sys/devices/ocp.3/pwm_test_P8_13.15/period
# so  10000000 = 0.01 seconds
echo 10000000 > /sys/devices/ocp.3/pwm_test_P8_13.15/duty

echo 20000000 > /sys/devices/ocp.3/pwm_test_P8_14.16/period
echo 10000000 > /sys/devices/ocp.3/pwm_test_P8_14.16/duty

And vuala, two pwm pins both running at 50%.

NOTE:

  • As the duty cycle increases, an LED will dim, i.e. 10M is brighter than 15M.
  • For my device, the path is /sys/devices/ocp.3/*, however another has reported their path to be located at /sys/devices/ocp.2/*. cd to /sys/devices and type 'ls' to list available titles.
Here is yet another pinout diagram mapping pwm and timer pins in yellow, provided on BeagleBoard.org.


More Pins!
Sometimes what is available is still not enough! But, no worries; there is a way to acquire about an additional 20 pins - which include additional UARTs and PWMs. To do this, we must disable the auto-loading of the HDMI cape (assuming you will not need a display to work on):
cd /home/debian/Desktop
# cd /home/root/Desktop - for Angstrom distros
mkdir card
mount /dev/mmcblk0p1 card
nano card/uEnv.txt
# uncomment 'optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN'
# BE WARNED! If you disable the eMMC as well, you will never be able to access your bone again save it be through an SD card and would need to reinstall Linux otherwise. The eMMC is like your hard drive - you don't need it if and only if you boot from an SD card (like the blue steel bone)
# Save
umount card
rm -rf card
reboot


Happy exploring the Internet of Things!

Wednesday, February 12, 2014

Vertical MenuStrip in C#

As part of a long term project which requires the creation of many custom controls, I recently encountered a hang-up on one in particular: the menu. At a first glance, all there really needs to be done is to override the various paint methods in an extended version of the ToolStripRenderer class and insert my fancy drawing code. However, the real problem came when I needed to render a menu like a ContextMenuStrip only in a window.

With a bit of quick research and perusing through the libraries, I learned of the Layout feature and how Dock still works even in MenuStrips. By setting Dock to Fill and Layout to VerticleStackWithOverflow, I should get the desired result right. Not so! This was still a menu and menu's do not render hot-keys, images, check-states, or ancestry. I didn't know it yet, but three days later (three days of hacking together something clunky by similar) I realized I could mask the under-the-hood functionality with emulation using the very same custom renderer that makes my menus look pretty.

My end result, a windowed context menu:

Solution:
In the method call to 'OnRenderMenuItemBackground,' make an additional call to OnRenderItemText (for the shortcut display string), OnRenderArrow (only if the item has children), and OnRenderItemCheck (only if the item is marked as checked). You will need to give your own rectangles but that's all part of the fun of rendering!


Some may ask: "What use does this have?"
The answer is simple; Based on developer feedback from professional media industries, when one has over a hundred or so menu items to choose from, the user can get lost real quickly. And even if they knew where things are, it still requires a bit of time to navigate the menu hierarchy before finally selecting the very menu item. If you have ever been involved in a large scale project where deadlines need to be met, you will agree that time is precious. Accessing the menu item may take only a second or two in real time, but this all adds up. So a solution like this is more of a necessary optimization: The user selects the key menu that is accessed often and turns it into a painter's pallet. And when they're done, they simply close the window - the menu will still be available where all other menus are located.