A different kind of college course

 

Bluetooth is not an easy thing to deal with, my instructor tells me. I didn’t believe him, and spent several fruitless weeks trying to get the Morse code Bluetooth chat app to work correctly.

The nature of application development, especially when it’s for a platform other than the one you write code on, is that you constantly stumble over bugs, weirdness and strange errors that aren’t your fault at all. It’s discouraging.

Even so, the course I’m currently taking in Android application development is the most interesting one I’ve had in my two-year Computer Systems Tech diploma program.

It was supposed to be about computer graphics. But the guy meant to teach it dropped out for some reason, and another teacher, here referred to as Robocop to protect his privacy, stepped in.

Robocop had about 3 weeks to come up with a curriculum, so the normal method of curriculum development wasn’t going to work. Instead he used the considerable leeway that the college allowed, to construct an experiment.

6 projects – students proposed and voted on ideas. (Time savings for the teacher – no assignment development).

Anyone can work in any project they want. Download the source from git, decide what you want to do, and do it. Push the changes, then sit back and wait for everyone else to bawl at you for breaking the build. Marking is done by peer reviews. You get a mark out of 10 based on whatever you’ve done this week, so anyone who makes a reasonable effort and documents it can have a perfect score. (Theoretical time savings for teacher – no assignment marking.)

The great thing is, you get as much out of it as you put in. You could do the bare minimum of testing code and maybe tossing out a toString or a small refactor once in a while, or you could rally a team, spend night and day working on, talking about, living in it, and create a commercial grade application from scratch, in three months, with adult supervision the whole time. (Now that I’m an adult I freaking loooove having adult supervision. Takes so much pressure off.)

I wouldn’t say it’s a 100% success – Robocop originally thought that we’d be able to come up with 6 commercially viable, clean, usable Android apps by the end of quarter. I think we’ll be lucky if even one of them technically does what we originally set out to do. Some people wasted a lot of time being confused, asking “What am I supposed to do? Where are the instructions?”

But as an experiment, it’s a home run. As education, it’s exactly what I wanted out of college. Preparation for working with people you don’t necessarily like, who might make brilliant decisions sometimes and really odd ones other times. The hot shame of responsibility for ruining weeks of other people’s work. The freedom to make whatever you want, if you can get the others to play along. I don’t know if the course will work long term for the college, since all the time Robocop saved before class started, he has to pay back trying to keep up with 6 open projects. I hope they keep it.

For me, personally, it’s not a success yet. Not until I can get the stupid Bluetooth connection to work right.

 

 

Signals, Pulses, and Messages in C

Further studies in pulses…messages… AND SIGNALS!

Sorry. Signals don’t rate capslock, tbh. But I shall attempt to teach you about them.

The usual includes. msg.h is my teachers’ concoction, and may be found here.

 

Gonna need some globals – the main and a couple of helpter functions both need to access the logfile, the channel id, and the timestruct.

Begin!

 

Initialize the timestruct, cos it is no longer 1970 and I am not Dennis Ritchie.

 

The void pointer – a promise of a method, soon to be revealed.

 

That logfile declaration from above? Time to use it! This is nothing more than a textfile where your program is going to write some stuff down.

 

A couple more variables; theMessage is a handle for data that is received from the client. rcvid will be used to tell the client which of it’s many messages you are currently replying to.

 

Upon startup, this message logger will report its process id, channel id, and node descriptor, and log that info in a pidfile. As I write this I can’t help noticing that chid isn’t initialized yet. I really hope I figure out an explanation for that later.

 

This bit is kinda weird. These two functions are both at the bottom of this program, so you’re sending pulses and signals to yourself. Why do that? Narcissism? Shpakism? Just do it.

This is also weird. You’re bascially announcing, “Hey, a signal might show up, and if it does, here’s what you do.” And that instruction is standing orders for the rest of the program, or til you change it.

K, with all that established, begin a for loop that will run until further notice, taking messages and reporting them in the logfile.

Now, this part confuses me. Cause I thought that a pulse was just a message, with a rcvid of zero. But the teacher has us, apparently, handling two cases that both match the definition of “pulse” in my mind.

So, the first “if” handles rcvid == 0.

The second “if” redirects to a helper method that has the same big switch statement from my previous post. It also handles a “pulse”, and like I said, I’m confused. However, I swear to god this code runs and drive as written.

Take note of the timeToQuit int there. It takes the return value of the handleMessage function – if the message was a … sigh … pulse, I guess … it returns something other than zero, which terminates the loop, and the program.

So where are these pulses and signals coming from? Upsettingly, they are coming from within this very program.

Here’s the setup for a pulse. It is straight out of Getting Started With QNX Neutrino, which can be found here, page 152. RTFM fools.

The signal setup works almost exactly the same, there’s like one line that’s different.

My message handler. It logs a message if a message turns up, and shuts the whole show down if a confusingly explained pulse shows up.

And finally, the signal handler. It’s pretty easy.

And that’s the whole mess. It runs on my machine; I take no responsibility if it causes your computer to have a stroke instead. Here’s the finished code.

How to write a message logger in C

You are probably here because some demanding professor has ordered you to produce an example of a program that recieves messages and pulses and logs stuff about them.

Here I will provide  the answer to all your questions. Well, some of your questions.

I can’t, for example, tell you why you decided to take this stupid degree in the first place.
I can’t tell you where to find true love, or the secret of happiness.

I can’t even tell you how to code – I can attempt to give you some information, but everyone basically has to teach themselves how to program. Also, I apologize for the formatting – wordpress’s text editor is literally the worst thing in the universe.

Oh well, read on if you must.
First, some inclusions. The usual suspects – we’ll need the ability to write to the command line, concatenate a string, make timestamps.

“msg.h” is a header file provided by my teacher. There’s a bunch of stuff in there, but the important bits are:

The message header can be accessed by theMessage.m_hdr. Pulses can send codes, and this particular pulse code can be accessed with theMessage.pulse.code. I can’t remember what the rest of the includes are for. I might’ve copied them from a different lab.

Begin!

First, we’re going to need a bunch of variables.

You could probably write a better usage message. This just means that the program was called with too few arguements – no logfile was specified, so it doesn’t know where to store logs.

Establish a connection to whatever client program is trying to get ahold of you. This function will not execute until the client shows up.

When the client does show up, its process id, channel id and node descriptor will be recorded in the pidfile, via this bit:

Then open the logfile to record whatever messages the client wants to send.

At this point, you’re going to start an infinite while loop. It will keep running as long as the client wants to keep sending messages. It only terminates when the client sends a pulse.

In each iteration of the while loop, the logger looks for a new message and stores it at theMessage’s memory location. The timestruct initalization doesn’t have to be in the while loop, but there it is. It does have to exist though, cause if you don’t initialize the timestruct then it will just claim that it’s Jan 1 1970. You can pass arguments to specify a time format, or just send it null for the default.

Next is a switch to check the message header to see what sort of thing it is.

  • If it’s a regular message, it’ll have a unique rcvid.
  • If it’s a pulse, the rcvid will be 0, since you don’t need to reply to pulses. The whole idea of a pulse is that it’s non-blocking – it doesn’t wait for a reply. Kinda like HTTP, in that pulses sends out messages and hope for the best. If no acknowledgement arrives after while it just gives up./li>

The first case, a proper message arrives. Report on the command line that something happened, and log the item and the date. Reply with an acknowledgement that the message is fine, flush the buffer, and carry on.

In this program, we’re using pulses to terminate the logger program. So if a pulse arrives,

You know it’s a pulse because the theMessage.m_hdr == 0, though it’s translated to the enum MSG_ENG for the sake of readability.

If anything other than a pulse or a valid message turns up, the logger just shrugs and carries on.

And that’s basically it – just clean up and exit.

The Complete Code

I hope it’s helpful. I also hope you actually understand it, rather than just turning it in as is.

msg.h