16 Commits
v0.1 ... v0.2

Author SHA1 Message Date
Gerolf Ziegenhain
f222d65bd8 moved x86 stuff to src 2015-01-04 10:06:40 +01:00
Gerolf Ziegenhain
840bbd0c04 typo 2015-01-04 02:36:57 +01:00
Gerolf Ziegenhain
50dfd48602 additional information 2015-01-04 00:12:56 +01:00
Gerolf Ziegenhain
5ffefff868 additional information 2015-01-04 00:04:09 +01:00
Gerolf Ziegenhain
dd72972a96 additional information 2015-01-03 23:59:18 +01:00
Gerolf Ziegenhain
572345d34b references 2015-01-03 23:45:14 +01:00
Gerolf Ziegenhain
04572c6c16 references 2015-01-03 23:42:00 +01:00
Gerolf Ziegenhain
f7b1bf6e1e references 2015-01-03 23:39:12 +01:00
Gerolf Ziegenhain
4c02a54109 formatting 2015-01-03 23:28:04 +01:00
Gerolf Ziegenhain
7e8c1803af formatting 2015-01-03 23:26:48 +01:00
Gerolf Ziegenhain
247deb12dc formatting 2015-01-03 23:26:01 +01:00
Gerolf Ziegenhain
6e141246f6 formatting 2015-01-03 23:19:29 +01:00
Gerolf Ziegenhain
8f77f51fcf linux installation notes 2015-01-03 23:15:12 +01:00
Gerolf Ziegenhain
c8105acca0 linux notes 2015-01-03 23:14:25 +01:00
Gerolf Ziegenhain
b2f24af29e merged linux build 2015-01-03 23:12:02 +01:00
Gerolf Ziegenhain
0b242efc1a merged linux build 2015-01-03 23:11:45 +01:00
5 changed files with 143 additions and 142 deletions

117
README.md
View File

@@ -1,41 +1,98 @@
=== WIP - Snipplets === irmc - Internet Relay Morse Code
How to use: ================================
1 usage: irmc [hostname] [port] [channel] [id] [serialport] # What is IRMC?
./irmc mtc-kob.dyndns.org 7890 103 123 /dev/tty.usbserial IRMC stands for Internet Relay Morse Code. It implements the [CWCom protocol](http://kob.sdf.org/morsekob/docs/cwcom.pdf) as adopted by [MorseKOB](http://kob.sdf.org/morsekob/docs/history.pdf). You can try out the software in a [browser](http://kob.sdf.org/morsekob/morsekob30/index.htm) using Java.
faeroes.sdf.org.7890
## Why morse code over IP?
Why not? A number of different approaches for CW over IP exist. An early implementation has been the CWCom protocol,
which has been the basis for Morse KOB, a ready-to-use software. Both chat programs have been written for CW exclusively and are compatible. An alternative implementation in C exists as well as a port to the ATMEL AVR Microcontroller.
Besides a variety of other approaches exist, for example an IRC plugin ([CWirc](http://myspace.voo.be/pcoupard/cwirc/)), a [JavaScript implementation](http://morsecode.me), a [bandwidth-eating UDP implementation](http://hans.liss.pp.se/node/343), a [chat for iOS](http://pignology.net/cwwithme.html) or a modulated CW over IP using Mumble ([iCW](https://sites.google.com/site/icwoip/)).
TBD: Driver: # How to build?
serial - 2usb! ## Install dependency: morse keyer library
```
wget https://github.com/8cH9azbsFifZ/morse/archive/v0.1.tar.gz
tar xzf v0.1.tar.gz
cd morse-0.1
libtoolize
./autogen.sh
./configure --with-portaudio
make
sudo make install
```
TBD: OSX - howto install dependencies ## Debian (Wheezy)
Some dependencies have to be installed:
```
apt-get install -y alsa-oss oss-compat build-essential autoconf libao-dev libtool
```
Afterwards compilation with `make` should work. If something went wrong, you may have
to adjust your `LD_LIBRARY_PATH`. Alternatively try:
```
LD_LIBRARY_PATH=/usr/local/lib ./irmc mtc-kob.dyndns.org 7890 33 123
```
=== Original post === ## OSX (Yosemite)
I have been using cwcom to practice sending morsecode, unfortunately my main computer at home is running openbsd and it has gotten harder to gain access to a reliable MS Windows machine. So I wrote my own client that works on openbsd. Compilation with make :)
This is written in C and although not tested it should compile under other OS. If any one wants to try it and send me feedback. you can download version 0.01 here http://fernan.bitbucket.org/irmc.tgz
Les Kerr of https://home.comcast.net/~morsekob/ has been very patient in answering my questions regarding the cwcom protocol and setting up a test server during debugging.
There are few difference between this and the official cwcom client For the USB serial devices you need a PL2303 driver (i.e. PL2303_Serial-USB_on_OSX_Lion.pkg).
1. It is a command line tool
2. It does not send the characters of the message to the receivers screen.
3. It does not translate CW for you. You can try fldigi if you just want see the transmission.
4. Tone pitch is currently hard coded to 650Hz
5. It does not have a way to show you who is listening.
Bugs ## Testing with MorseKOB 3.0 (Java)
There are a few that I am working on right now, but feel free to send me feedback if you get a chance to try it out. This [software](http://kob.sdf.org/morsekob/morsekob30/MorseKOB.jar) will run on
Linux, Windows and OSX. With the [RXTX software](http://morsekob.org/morsekob30/help.htm)
File(s) for Java (i.e. librxtxSerial.jnilib on OSX) it is even possible to connect to external hardware.
http://fernan.bitbucket.org/irmc.tgz NB: before you transmit make sure you uncheck the "circuit closer".
Resources # How to use:
The following people have helped me a lot to learn the protocols and setting up test servers.
Les Kerr - https://home.comcast.net/~morsekob/
Bob Denny - http://morse-rss-news.sourceforge.net/
John Samin - http://www.mrx.com.au/
=== Source: http://fernski.blogspot.de/2013/03/internet-relay-morsecode.html === The usage is: `irmc [hostname] [port] [channel] [id] [serialport`
=== End Original Post ===
For example:
`./irmc mtc-kob.dyndns.org 7890 103 MyID /dev/tty.usbserial´
## Morse KOB Servers
* faeroes.sdf.org 7890
* mtc-kob.dyndns.org 7890
A current list of servers if provided on the [MorseKOB Website](http://mtc-kob.dyndns.org).
## Hardware interface options
A good description on how to build differnt interfaces (telegraph key, sounder or both) is given on the [MorseKOB Website](http://kob.sdf.org/morsekob/interface.htm). Landline telegraphs use "closed circuits" for communications; if you have built one at home, you may also use the [loop interface](http://kob.sdf.org/morsekob/docs/loopinterface.pdf).
# References
## Original post by Fernan Bolando (VE4FEB)
Copied on 20150103 from http://fernski.blogspot.de/2013/03/internet-relay-morsecode.html
> I have been using cwcom to practice sending morsecode, unfortunately my main computer at home is running openbsd and it has gotten harder to gain access to a reliable MS Windows machine. So I wrote my own client that works on openbsd.
> This is written in C and although not tested it should compile under other OS. If any one wants to try it and send me feedback. you can download version 0.01 here http://fernan.bitbucket.org/irmc.tgz
> Les Kerr of https://home.comcast.net/~morsekob/ has been very patient in answering my questions regarding the cwcom protocol and setting up a test server during debugging.
>
> There are few difference between this and the official cwcom client
> 1. It is a command line tool
> 2. It does not send the characters of the message to the receivers screen.
> 3. It does not translate CW for you. You can try fldigi if you just want see the transmission.
> 4. Tone pitch is currently hard coded to 650Hz
> 5. It does not have a way to show you who is listening.
>
> Bugs:
> There are a few that I am working on right now, but feel free to send me feedback if you get a chance to try it out.
>
> File(s)
> http://fernan.bitbucket.org/irmc.tgz
> The following people have helped me a lot to learn the protocols and setting up test servers.
> Les Kerr - https://home.comcast.net/~morsekob/
> Bob Denny - http://morse-rss-news.sourceforge.net/
> John Samin - http://www.mrx.com.au/
## Resources
* CWCom, John Samin (VK1EME): http://www.mrx.com.au/d_cwcom.htm
* Morse KOB, Les Kerr: https://sites.google.com/site/morsekob/ and http://kob.sdf.org/morsekob/
* Relay server for CW communicator and morse KOB: http://morsecode.dc3.com:7890
* Sources for the Relay Server: http://sourceforge.net/projects/morse-rss-news/
* MorseKOB for AT Mega, Fernan Bolando (VE4FEB): http://fernski.blogspot.de/2013/05/sending-morsecode-via-atmega.html

94
sound.c
View File

@@ -1,94 +0,0 @@
/* irmc - internet relay morsecode client */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <soundcard.h>
#include <math.h>
#define SAMPLE_RATE 48000
int sample_rate = SAMPLE_RATE;
int fd_speaker;
int zinebuf[SAMPLE_RATE * 2];
int pitch = 650;
void
init_sound()
{
int i, pr;
pr = sample_rate / pitch;
for(i = 0; i < SAMPLE_RATE * 2; i++)
zinebuf[i] = 32767 * sin(2 * 3.1415 / pr * (double)i );
}
void
play_code_element (int length)
{
int i;
short buf[SAMPLE_RATE * 4];
int outsz;
outsz = abs(length) * SAMPLE_RATE / 1000;
if(length == 0 || abs(length) > 2000) return;
if(length < 0) { /* Space */
for (i = 0; i < outsz; i++) buf[i] = 0;
} else { /* Mark */
for (i = 0; i < outsz; i++) buf[i] = zinebuf[i];
}
if (write (fd_speaker, buf, outsz * 2) != (outsz * 2)){
perror ("Audio write");
exit (-1);
}
}
int
open_audio_device (char *name, int mode)
{
int tmp, fd;
if ((fd = open (name, mode, 0)) == -1){
perror (name);
//exit (-1);
}
tmp = AFMT_S16_NE; /* Native 16 bits */
if (ioctl (fd, SNDCTL_DSP_SETFMT, &tmp) == -1){
perror ("SNDCTL_DSP_SETFMT");
exit (-1);
}
if (tmp != AFMT_S16_NE){
fprintf (stderr,
"The device doesn't support the 16 bit sample format.\n");
exit (-1);
}
tmp = 1;
if (ioctl (fd, SNDCTL_DSP_CHANNELS, &tmp) == -1){
perror ("SNDCTL_DSP_CHANNELS");
exit (-1);
}
if (tmp != 1){
fprintf (stderr, "The device doesn't support mono mode.\n");
exit (-1);
}
//sample_rate = 48000;
if (ioctl (fd, SNDCTL_DSP_SPEED, &sample_rate) == -1){
perror ("SNDCTL_DSP_SPEED");
exit (-1);
}
return fd;
}

View File

@@ -1,3 +0,0 @@
void init_sound (void);
void play_code_element (int);
int open_audio_device (char *, int);

View File

@@ -1,7 +1,7 @@
SRC = irmc.c sound.c SRC = irmc.c
OBJ = ${SRC:.c=.o} OBJ = ${SRC:.c=.o}
LDFLAGS = -lm -lossaudio LDFLAGS = -L/usr/local/lib -L/opt/local/lib -lm -lmorse
CFLAGS = -Wall CFLAGS = -I/usr/local/include -I/opt/local/include -Wall
INSTALLDIR = ${HOME}/bin INSTALLDIR = ${HOME}/bin
all: options irmc all: options irmc

View File

@@ -11,10 +11,26 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <math.h> #include <math.h>
#include <fcntl.h> #include <fcntl.h>
#include <soundcard.h> #include <morse/beep.h>
#ifdef __MACH__
#define LIBOSS_INTERNAL
#include <liboss/soundcard.h> //will not be used for audio any more
#else
#include <linux/ioctl.h>
#include <asm-generic/ioctl.h>
#include <asm-generic/termios.h>
#endif
#include <signal.h> #include <signal.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "sound.h" #include <time.h>
#include <sys/time.h>
#include <stdio.h>
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#define MAXDATASIZE 1024 // max number of bytes we can get at once #define MAXDATASIZE 1024 // max number of bytes we can get at once
@@ -73,7 +89,6 @@ long tx_timer = 0;
#define TX_TIMEOUT 240.0 #define TX_TIMEOUT 240.0
#define KEEPALIVE_CYCLE 100 #define KEEPALIVE_CYCLE 100
char soundcard[] = "/dev/audio";
long key_press_t1; long key_press_t1;
long key_release_t1; long key_release_t1;
int last_message = 0; int last_message = 0;
@@ -83,6 +98,22 @@ char last_sender[16];
int translate = 0; int translate = 0;
int audio_status = 1; int audio_status = 1;
/* portable time, as listed in https://gist.github.com/jbenet/1087739 */
void current_utc_time(struct timespec *ts) {
#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts->tv_sec = mts.tv_sec;
ts->tv_nsec = mts.tv_nsec;
#else
clock_gettime(CLOCK_REALTIME, ts);
#endif
}
/* a better clock() in milliseconds */ /* a better clock() in milliseconds */
long long
fastclock(void) fastclock(void)
@@ -90,7 +121,7 @@ fastclock(void)
struct timespec t; struct timespec t;
long r; long r;
clock_gettime(CLOCK_REALTIME, &t); current_utc_time (&t);
r = t.tv_sec * 1000; r = t.tv_sec * 1000;
r = r + t.tv_nsec / 1000000; r = r + t.tv_nsec / 1000000;
return r; return r;
@@ -221,12 +252,10 @@ commandmode(void)
if((strncmp(cmd, "aon", 3)) == 0){ if((strncmp(cmd, "aon", 3)) == 0){
audio_status = 1; audio_status = 1;
fd_speaker = open_audio_device(soundcard, O_WRONLY);
return 0; return 0;
} }
if((strncmp(cmd, "aoff", 3)) == 0){ if((strncmp(cmd, "aoff", 3)) == 0){
audio_status = 0; audio_status = 0;
close(fd_speaker);
return 0; return 0;
} }
printf("?\n"); printf("?\n");
@@ -278,7 +307,6 @@ int main(int argc, char *argv[])
char id[128]; char id[128];
char serialport[64]; char serialport[64];
if (argc < 4) { if (argc < 4) {
fprintf(stderr," %i usage: irmc [hostname] [port] [channel] [id] [serialport]\n", argc); fprintf(stderr," %i usage: irmc [hostname] [port] [channel] [id] [serialport]\n", argc);
exit(1); exit(1);
@@ -354,7 +382,7 @@ int main(int argc, char *argv[])
inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
s, sizeof s); s, sizeof s);
printf("irmc: connected to %s\n", s); printf("irmc: connected to %s\n", s);
fd_speaker = open_audio_device(soundcard, O_WRONLY); beep_init();
fd_serial = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY); fd_serial = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd_serial == -1) { if(fd_serial == -1) {
printf("irmc: unable to open serial port.\n"); printf("irmc: unable to open serial port.\n");
@@ -362,7 +390,6 @@ int main(int argc, char *argv[])
freeaddrinfo(servinfo); /* all done with this structure */ freeaddrinfo(servinfo); /* all done with this structure */
key_release_t1 = fastclock(); key_release_t1 = fastclock();
init_sound();
identifyclient(); identifyclient();
/* Main Loop */ /* Main Loop */
@@ -398,7 +425,22 @@ int main(int argc, char *argv[])
break; break;
default: default:
if(audio_status == 1) if(audio_status == 1)
play_code_element (rx_data_packet.code[i]); {
int length = rx_data_packet.code[i];
if(length == 0 || abs(length) > 2000) {
}
else
{
if(length < 0) {
beep(0.0, abs(length)/1000.);
}
else
{
beep(1000.0, length/1000.);
}
}
}
break; break;
} }
} }
@@ -442,7 +484,6 @@ int main(int argc, char *argv[])
send(fd_socket, &disconnect_packet, sizeof(disconnect_packet), 0); send(fd_socket, &disconnect_packet, sizeof(disconnect_packet), 0);
close(fd_socket); close(fd_socket);
close(fd_speaker);
close(fd_serial); close(fd_serial);
exit(0); exit(0);