Friday, August 30, 2013

CIVIC: Almost Alive

Well, the Civic is almost alive.  It runs, and I've driven it almost 20 miles since the swap.  However, it's only legal right now because I have a permit on it.  The reality is - it failed the safety and the emissions checks.

Emissions Inspection :

When I finally snuck it in to get it inspected, I had completely forgotten that if you disconnect the battery for any extended period, the computer's memory completely resets, and all of the emissions equipment settles into a "Not Ready" state until you have enough regular driving conditions on the car for it to figure out how it is doing.  So, it failed the emissions because everything was in a "not ready" state.

Safety Inspection :

The safety inspection wasn't as bad as it could have been.  Shoot, the last time it was inspected, I was surprised it passed because the tires were so worn out.  I didn't expect them to pass this time, and wasn't shocked when that didn't happen.  I'll get it to Les Schwab in the next few days and then get it registered.

Result :

Today's drive was a good, longer than 9 months of driving kind of drive.  I put 15 miles on it in a half hour, but none was freeway.  I have a 15 day period to get the good driving results in, and get it registered.  Then I'll be completely back on my feet.  It was good city driving, and the car didn't want to move as easily at first, but slowly started to loosen up again.  I think it will be back to normal within a week with my driving habits.

That said, it's allowed me to work on the Corvette a little bit - and I was able to get that alarm key set up, and duplicated.  Now, I just need to install the switch and wiring, and then hit the electrical with some probes to ensure things are lined up in the right places.  Perhaps after a good day of work on it on Monday can get me feeling better about it.  I might be able to get the steering column put back together.  Hooray!

Wednesday, August 28, 2013

Corvette - Alarm Key Working

So, I had purchased an alarm switch off of eBay a while back for the Corvette (while working on the Civic).  I finally got around to having a lock smith take a look at the switch (I had no key, and it was advertised as "filling a hole" and was in "rough shape" according to the photos).  I had held the thing in my hand numerous times, and I've been wondering if it's possible to restore it to functionality.

Well, I finally overcame my fear and headed to the lock smith.  $26 later, I had the following :

  • A functional key to fit the switch - I needed to have them re-key, but didn't have that key with me.
  • Electrical testing operates as designed.
  • A feel good "That's the cleanest set of tumblers I've ever seen on something that old - I think they just never used it."
I'd install it, but I have one thing left to do - get it re-keyed to match the new ignition keys. Once that is done, it's time to install it, check the electrical, and then connect a battery so that I can get the window glass adjusted and the door and dash panels installed.  One small step, but it's been a hurdle.

Wednesday, August 21, 2013

MisicBrainz Picard (and FFMpeg and Chromaprint) in CentOS

I had some unidentified tracks that I wanted to identify.  I knew that there were apps that would "listen" on the microphone of a phone to a song to identify it, and that lead me to believe that there would be a webservice out there I could call with the MP3's to identify them.

A quick Google search turned up a program called "Picard", by "MusicBrainz".  They even had a "Linux" interface for it.

For those who are impatient and want to install this, there are two dependencies - ffmpeg development packages (a result of the next dependency) and chromaprint.  Here's how to install everything :

  1. Install ffmpeg by doing :
    1. Using RPMForge, follow the instructions at : http://wiki.centos.org/AdditionalResources/Repositories/RPMForge#head-f0c3ecee3dbb407e4eed79a56ec0ae92d1398e01
    2. Then, install ffmpeg and libraries :
      yum install ffmpeg ffmpeg-devel
  2. Install chromaprint (download, extract, and CD into the directory - remember, we installed ffmpeg to an odd directory above, tweak if this is in a normal place) :

      cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON .
      make
      make install
      
      
  3. Ensure you have the libraries for chromaprint installed :
    all chromaprint (download, extract, and CD into the directory - remember, we installed ffmpeg to an odd directory above, tweak if this is in a normal place) :

      ldconfig -p|grep chroma
      

    If nothing shows up, add /usr/lobal/lib to /etc/ld.so.conf and run "ldconfig" again.
  4. Install picard by grabbing the code from http://musicbrainz.org/doc/MusicBrainz_Picard, extract it, cd into it, and run :

      python setup.py install

    This should install it for you.  Run it using the command picard.
For those that want to know how I got to this point, this is how I got it installed, and tried it.

First, I grabbed it from http://musicbrainz.org/doc/MusicBrainz_Picard (using the Linux source as I didn't want to deal with cross-distribution RPM's).  Pulling it down, I found it to be a python based installation (not the usual "./configure && make && make install").  I checked the INSTALL.txt and found what I needed.  Once inside the source directory, run :
    python setup.py install
This will install the code for you.  I also ran into a few issues with missing python modules.  The ones I had problems with are PyQt4.x86_64 and mutagen

So, in order to get the interface to launch, I had to run :
    yum install PyQt4.x86_64 python-mutagen.noarch
This allowed the interface to run, but I was getting :
    Fingerprint calculator failed error = No such file or directory (0)
This is a result of not having chromaprint's "fpcalc" program (the packages fingerprint calculator, which is actually sent to the web service and used to find the song information from an accoustic perspective).  In trying to get that one installed, I ran into the following error :
    FFTW3 lib not found. Set FFTW3_DIR to find it.
    CMake Error at CMakeLists.txt:114 (message):
      Neither FFmpeg with avfft.h nor FFTW3 found
Hrmmmm.  I need FFMpeg for the encoding, and it must apparently be the development.  That package starts to become a little "extreme" for a few people, but I was actually stunned that I hadn't installed it myself (it's usually one of the first things I install).  So, I had to install it.  It's a matter of following (standard instructions), and then :

yum install ffmpeg ffmpeg-devel
    yum install ffmpeg ffmpeg-devel
I had some conflict errors, so had to throw in a few "--disablerepo dag --disablerepo rpmforge" options and manually install a package, but got ffmpeg installed.  Next, I had to compile and install chromaprint :
    cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON .
    make
    make install
It tossed /usr/local/bin/fpcalc onto the filesystem, and this time, we got :
    Network request error for http://api.acoustid.org:80/v2/lookup: Error downloading http://api.acoustid.org:80/v2/lookup - server replied: BAD REQUEST (QT code 299, HTTP code 400)
    Fingerprint lookup failed: u'invalid fingerprint'
    
THEN I figured out the "scan" wasn't the right thing to do - invalid fingerprinting.  I was supposed to be using "locate", not "scan".  Cool!

Tuesday, August 13, 2013

Civic Status: running, SRS/CEL both clean

Okay, after breaking the valve cover bolt, I had to drill the bolt without touching the valve train/head, and then back it out.  I was successfully able to do that, dropped in the replacement bolt, tightened things down (very carefully, this time), and then crossed my fingers.....

... the car started, no CEL (not even the SRS, this time, either), and it seemed to be running much better.  Next up - grease the bearings on the wheels, pull a lug bolt and replace it, and go get it registered.  I don't know if the tires will pass an inspection, but if they don't, that would be it to be back on the road.  An A/C recharge would be next on the list, but it's workable without it.  So, three things to do before I can get back to the Corvette :
  1. Lug bolt/nuts
  2. Tires replaced
  3. Recharge/oil the A/C lines
This is phenomenal news!

Monday, August 5, 2013

Simple TCP Server in C - Republish

Security Note

If you need to set up a command server, there are a few issues. The first and foremost is security, though in the contexts of this document we will fore go the security issues. In this document we will discuss the ability to set up and create a simple server using unix and C/C++, leaving the discussion of securing a simple command server to a different document.

First, please be aware that running the resulting server as a root account could cause potential damage to the system (via hackers). So, this is only documented as research, with no liabilities held by the authors, consultants, or companies holding this code specifically as such.

Constructing the Program

First, we need to understand how a TCP/IP server even works. When a message is sent from a client to a server, it is encoded with an ID number, or a port as commonly referred to. Some port numbers are associated with a name, such as www (80), telnet (21), ssh (23), and SMTP/Mail (25). These are referred to as "common" ports. We need to identify the best port (preferrably one that is not used in any circumstances). I like to use the port 666 for software like this as it can be a real devil to secure. You will note that, in unix systems, one must be the root user in order to use privileged ports (ports under 1000), just to ensure the safety and well being of the "common" ports.

On the server itself, a piece of software called a daemon is running, and listening for connections that have the specified ID/port. When one comes in, it can then accept these connections, and recieve and transmit data to/from the other end of the connection (client).

An endpoint for TCP/IP communication is called a socket. The header file is called "sys/socket.h" (except in MS Windows where it is "winsock.h"). We will create a socket handle, using the socket function. Rather than opening the socket (a client will do this), bind to the socket, listen for incoming connections, and then accept them.

socket : This creates an endpoint, or a socket, to communicate with a client or a server on the network. It's use is :

int socket(int domain, int type, int protocol);

The integer returned is the handle to our socket.

bind : bind assigns the local port and server address to the socket. When a socket is created with the above socket command, it is classed only as a family (TCP is the AF_INET family, or internet type of socket). This can be used to request that a specific IP address will be listened to, or any IP address on the machine. The code :

int bind(int s, const struct sockaddr *addr, socklen_t addrlen);

listen : listen tells the program that incoming connections will be used. It also allows you to set things like queue limits for connections that clients have requested.

int listen(int s, int queued_connections);

accept : Once a socket has been created, assigned a port, and is listening for connections, you must call accept. Accept will block (meaning that it will wait until a connection request is made).

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

Creating the Source Code

We'll save the topic for creating a Makefile for a completely different discussion, as this can get extremely complex. In the mean time, use the following :
    # Makefile for a simple TCP Server
    
    PROGRAM =tcp_server
    CC      =gcc
    CCF     =-c
    LINKER  =ld
    LINKERF =-lc /usr/lib/crt1.o
    SRCS    =\
            main
    OBJS    =
    CCSRCS  =
    
    .for SRC in $(SRCS)
      OBJS += $(SRC).o
    .endfor
    
    all: compile link
    
    $(SRCS) :
            $(CC) $(CCF) $@.c -o $@.o
    
    compile: $(SRCS)
    
    link:
            $(LINKER) $(LINKERF) $(OBJS) -o $(PROGRAM)
    
    rmproper: clean
    
    clean:
            @rm *.o
            @rm $(PROGRAM)
    
Now, with this Makefile, all we will ever need to be worried about is adding source modules to the SRCS parameter (which already has a tcp and a main). The backslash is an escape method of saying "we're still adding stuff to the variable using the next line of information".

Okay, we need to have a 'main' function. The purpose of a 'main' function is to provide a uniform method for all C programs to be compiled. So, we create our function, and make it call our server code. If you want to add the ability to use command line options as you'll find on most tcp servers, this is the function you would add the code to. But, since all we need to do is start our TCP server, our function will be short :
    int main(void) {
            start_server(); /* start the tcp server */
            return 0;       /* return "success" to the shell */
    }
    
Nice and simple, eh? In fact, if you commented out that start_server(); line, and replace it with a printf("Hello, World!");, and you've got yourself the infamous "Hello, World!" program that is taught as the first step in C Programming.

But that's not what we're after. We are going to assemble a simple TCP command server. So, we leave the start_server(); line in place, and add a function called start_server(). It should take no parameters, because our example program is purely designed to be as simple as can be.

Prior to performing any socket operations, we will need to make sure we've got the right headers. Of we don't, compiling will fail the program. The headers we'll need are :
      #include <sys/types.h>
      #include <sys/socket.h>
      #include <netinet/in.h>
      #include <netdb.h>
    
Once you've got those, the following functions should be okay.

Inside of the function, we will need to create and prepare our socket. First, we create the socket handle (which is an integer) by creating an integer variable and assigning to it the result of calling the socket(AF_INET,SOCK_STREAM,getprotobyname("tcp")). The AF_INET declaration is specifically for the Internet, and the SOCK_STREAM number for the type is required for TCP data. We can typecast the return value of the getprotobyname to int just to keep from getting a lot of warning messages. But, here in our example, we'll just use 0 for that.

Once we have the socket handle created and initialized, we then bind the socket address information to our new socket handle. We first fill out the socket information, setting the address to the IP we are going to bind to (INADDR_ANY if we want to open up to any IP address), and also set the socket's family (the AF_INET is used twice, once for the operating system using the connect function call, and once for the socket information itself). We then push these parameters into the socket information using the bind() function, as in :

bind(our_socket_handle,(struct sockaddr *)&socket_info,sizeof(socket_info)).

Now, before proceding, I MUST hit on a key programming factor. ALWAYS check the status of a function if it returns it. The last thing you need to do is try a function call on an already defunct socket handle. So, PLEASE check the status of the bind function.
    int start_server(void) {
     int                  our_socket_handle,status;
     struct sockaddr_in   socket_info;
    
     our_socket_handle = socket(AF_INET,SOCK_STREAM,0);
     if (our_socket_handle == -1) {
      perror("Creating socket()");
      exit(1);
     }
    
     socket_info.sin_family      = AF_INET;              /* Internet TCP/IP              */
     socket_info.sin_addr.s_addr = htonl(INADDR_ANY);    /* listen on any IP address     */
     socket_info.sin_port        = htons(5000);          /* 5000 is an unprivileged port */
    
     status = bind(our_socket_handle,(struct sockaddr *)&socket_info,sizeof(struct sockaddr));
     if (status) {
      fprintf(stderr,"Cannot bind() to the socket");
      exit(1);
     }
    }
    
Now, we've bound the socket's information to it, so we need to listen() and accept() connections. Here's how we do that.

Listen is a straight forward function. All it is designed to do is tell the operating system that we are waiting for connections on the socket. We also include the number of back logged, or queued connections that we will allow to wait for our program (in this example, we'' listen for 5 connections), e.g. :

status = listen(our_socket_handle,5);.

Then we put a loop function around the accept() function. This allows us to retrieve an unlimited number of connections (though still at one at a time). But, since this is a simple tutorial, we will NOT put the accept in a loop. All we will do is retrieve the information that is sent, send it back, and exit. It's primarily a simple procedure to test with.

This accept() function is designed to recieve a connection. It will block until a connection is recieved, then proceed to the next line of code. It initializes a socket structure with the clients connection, and then releases you to work. Don't forget that the return variable, client_socket_handle, needs to be declared in the variables at the top. We also add the client_socket_info structure, and we're ready to implement it. Also, don't forget to close the sockets :
    status = listen(our_socket_handle,5); if (status) { fprintf(stderr,"Cannot listen() to socket"); exit(1); } client_socket_handle = accept(our_socket_handle,(struct sockaddr *)&client_socket_info,sizeof(struct sockaddr)); write(client_socket_handle,"Hello, World!",strlen("Hello, World!")); close(client_socket_handle); close(our_socket_handle);
Now, with this entire program, if you were to run it, it should not give you the command prompt back. Now, open up another telnet window, and go to the server you are running this on, at port 5000, and you should get an immediate close of the connection, but it should have printed the "Hello, World!" string before closing. Pretty snazzy, eh? Using a combination of the send() and recv() functions, you can build an effective communication tool to do nearly anything you need. Effectively, here is our main.c file :
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    
    int main(void) {
     start_server(); /* start the tcp server */
     return 0; /* return "success" to the shell */
    }
    
    int start_server(void) {
     int                  our_socket_handle,client_socket_handle,socket_size,status;
     struct sockaddr_in   socket_info;
     struct sockaddr_in   client_socket_info;
    
     our_socket_handle = socket(AF_INET,SOCK_STREAM,0); //(int)getprotobyname("tcp"));
     if (our_socket_handle == -1) {
      perror("Cannot create the socket : ");
      exit(1);
     }
    
     socket_info.sin_family = AF_INET;
     socket_info.sin_addr.s_addr = htonl(INADDR_ANY);
     socket_info.sin_port = htons(5000);
    
     status = bind(our_socket_handle,(struct sockaddr*)&socket_info,sizeof(struct sockaddr));
     if (status == -1) {
      perror("Cannot bind() to socket : ");
      exit(1);
     }
    
     status = listen(our_socket_handle,5);
     if (status == -1) {
      fprintf(stderr,"Cannot listen() to socket");
      exit(1);
     }
    
     socket_size = sizeof(struct sockaddr);
     client_socket_handle = accept(our_socket_handle,(struct sockaddr *)&client_socket_info,&socket_size);
     write(client_socket_handle,"HELLO, WORLD!",strlen("HELLO, WORLD!"));
     close(client_socket_handle);
     close(our_socket_handle);
    };