/*
*
* description of data file
*
* N max_grp max_mem
* G num yomi kanji
* M num grp secret yomi kanji phone
* #, balnk line : comment
* delimiter is TAB
*/
#include "config.h"
#ifdef DEBUG
/*
#define DPRI(args...) fprintf(stderr, ## args)
*/
#define DPRI(a) fprintf a
#define DPRI1(a) fprintf(stderr, a)
#define DPRI2(a,b) fprintf(stderr, a,b)
#define DPRI3(a,b,c) fprintf(stderr, a,b,c)
#define DPRI4(a,b,c,d) fprintf(stderr, a,b,c,d)
#else
/*
#define DPRI(args...)
*/
#define DPRI(a)
#define DPRI1(a)
#define DPRI2(a,b)
#define DPRI3(a,b,c)
#define DPRI4(a,b,c,d)
#endif
#define MSG1(a) if (verbose) fprintf(stderr, a)
#define MSG2(a,b) if (verbose) fprintf(stderr, a,b)
#define MSG3(a,b,c) if (verbose) fprintf(stderr, a,b,c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>
#if USE_TERMIO
#include <termio.h>
#define TERMIO struct termio
#endif
#if USE_TERMIOS
#include <termios.h>
#define TERMIO struct termios
#endif
#if HPUX
#include <sys/modem.h>
#endif
#ifdef HAVE_STDARG_H
# include <stdarg.h>
# define Va_start(a,b) va_start(a,b)
#else
# include <varargs.h>
# define Va_start(a,b) va_start(a)
#endif
#include "switchopt2.h"
#ifndef DEVICE
#define DEVICE "/dev/ttyS0"
#endif
#define BUFSIZE 2048
#define NUM_LEN 25
#define KIND_NUM 1
#define KIND_506G 1
typedef struct stkind {
char *str;
int num;
} kind_t;
kind_t cel_kind[] =
{
{"506g", KIND_506G},
};
int kind = 0;
typedef struct stceldb {
char *id, *desc;
int yomilen, kanjilen;
int ignoregroup;
int kanjicode;
} cel_db_t;
cel_db_t cel_db[] =
{
{"NSHPBD", "SH821i", 10, 16, 0, 0},
{"NSHPA", "SH811", 6, 12, 0, 0},
{"NMAPA", "P811", 10, 0, 1, 0},
{"NMACC", "P651i", 10, 0, 0, 0},
{"DKW94", "J-K31", 16, 16, 0, 0},
{"DSOP1", "J-SY01", 0, 0, 0, 0x02},
{NULL, NULL, 0, 0, 0, 0}
};
#define MAX_GRP 50
#define MAX_MEM 1000
#define STRLEN 40
#define ID_CELRW "CELRWK"
#define MAX_BYTE 255
#define LEN_MEM_YOMI MAX_BYTE
#define LEN_MEM_KANJI MAX_BYTE
#define LEN_GRP_YOMI MAX_BYTE
#define LEN_GRP_KANJI MAX_BYTE
#define MODE_READ 0
#define MODE_STORE 1
#define EOL -1
/* 8 bit */
/* even parity, stop bit = 1 */
/* 600 bps */
#define CLEAR_BITS ~(CSIZE | PARODD | CSTOPB)
#define SET_BITS (CS8 | PARENB)
#define UCHAR unsigned char
#define ALARMW set_action(); alarm(timeout); if (setjmp(jump_env) == 0)
#define ALARMWT(x) set_action(); alarm(x); if (setjmp(jump_env) == 0)
#define ELSE else
int timeout = 1;
jmp_buf jump_env;
char rcv_num_tbl[] = {'D', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '*', '#', 'A', 'B', 'C'};
char rev_num_tbl[] = {0x0a, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09};
#define NUM_BAUD 4
int valid_baud[] = {600, 2400, 4800, 9600};
TERMIO pmode;
#if HPUX
mflag mmode;
#endif
int mfd;
int baud;
int force_baud = 0;
char *device = DEVICE;
static UCHAR buf[BUFSIZE];
static char dummy[MAX_BYTE];
/* counter for send memory */
int n_grp = 0;
int n_mem = 0;
int nogroup = 0; /* 1: Group is not supported */
int max_grp, max_mem;
int file_grp_num[MAX_GRP];
UCHAR file_grp_yomi[MAX_GRP][STRLEN];
UCHAR file_grp_kanji[MAX_GRP][STRLEN];
int secret;
int file_mem_num[MAX_MEM];
int file_mem_grp[MAX_MEM];
int file_mem_secret[MAX_MEM];
UCHAR file_mem_yomi[MAX_MEM][STRLEN];
UCHAR file_mem_kanji[MAX_MEM][STRLEN];
UCHAR file_mem_phone[MAX_MEM][STRLEN];
int read_grp_num = 0, read_mem_num = 0;
int read_line;
int verbose = 1;
int yomi_len = 0;
int kanji_len = 0;
int ignore_group = 0;
int kanjicode = 0;
#if PORTWAIT
#include <sys/time.h>
void mwait(msec)
int msec;
{
struct timeval tv_;
struct timezone tz_;
double d1,d2,d3;
double w = msec * 1000.;
(void) gettimeofday(&tv_,&tz_);
d1 = tv_.tv_sec;
d2 = tv_.tv_usec;
do{
(void) gettimeofday(&tv_,&tz_);
d3 = (double) (tv_.tv_sec - d1) * 1000000.
+ (double) (tv_.tv_usec - d2);
}while ( d3 < w );
}
#endif /* PORTWAIT */
void Tcgeta(fd,tios)
int fd;
TERMIO *tios;
{
#if USE_TERMIO
if (ioctl(fd, TCGETA, tios) < 0)
#endif
#if USE_TERMIOS
if (tcgetattr(fd, tios) < 0)
#endif
{
perror("TCGETA");
exit(-1);
}
}
void Tcseta(fd,tios)
int fd;
TERMIO *tios;
{
#if USE_TERMIO
if (ioctl(fd, TCSETAF, tios)< 0)
#endif
#if USE_TERMIOS
if (tcsetattr(fd, TCSAFLUSH, tios) < 0)
#endif
{
perror("TCSETAF");
exit(1);
}
}
void Tcsetaw(fd,tios)
int fd;
TERMIO *tios;
{
#if USE_TERMIO
if (ioctl(fd, TCSETAW, tios)< 0)
#endif
#if USE_TERMIOS
if (tcsetattr(fd, TCSADRAIN, tios) < 0)
#endif
{
perror("TCSETAW");
exit(1);
}
}
void Flush()
{
Tcgeta(mfd, &pmode);
Tcsetaw(mfd, &pmode);
}
void change_baud(b)
int b;
{
Tcgeta(mfd,&pmode);
#if USE_TERMIO
pmode.c_cflag &= ~CBAUD;
pmode.c_cflag |= b;
#endif
#if USE_TERMIOS
cfsetospeed(&pmode, b);
cfsetispeed(&pmode, b);
#endif
Tcseta(mfd, &pmode);
}
void OpenDevice()
{
int temp;
#ifdef __OpenBSD__
if ((mfd = open(device, O_RDWR)) < 0)
#else
if ((mfd = open(device, O_RDWR | O_NDELAY)) < 0)
#endif
{
perror("Can't open device");
exit(-1);
}
#if HPUX
if (ioctl(mfd, MCGETA, &mmode) == -1) {
perror("MCGETA:");
exit(1);
}
mmode |= (MDTR | MRTS);
if (ioctl(mfd, MCSETAF, &mmode) == -1) {
perror("MCSETAF:");
exit(1);
}
#endif
Tcgeta(mfd, &pmode);
pmode.c_cflag &= ~(HUPCL);
pmode.c_cflag |= CLOCAL;
pmode.c_iflag = IGNBRK ;
pmode.c_oflag = pmode.c_lflag = 0;
pmode.c_cc[VMIN] = 1;
pmode.c_cc[VTIME] = 0;
pmode.c_iflag &= ~(IXON | IXOFF | IXANY);
/*
pmode.c_iflag |= IXON | IXOFF | IXANY;
*/
Tcseta(mfd, &pmode);
temp = mfd;
#ifndef __OpenBSD__
if ((mfd = open(device, O_RDWR)) < 0){
perror("Can't open device part2 ");
exit(-1);
}
close(temp);
#endif
change_baud(B600);
pmode.c_cflag &= CLEAR_BITS;
pmode.c_cflag |= SET_BITS;
Tcseta(mfd, &pmode);
}
void CloseDevice()
{
Tcgeta(mfd, &pmode);
pmode.c_cflag &= ~CLOCAL;
pmode.c_cflag |= B0 | HUPCL;
Tcseta(mfd, &pmode);
#if HPUX
if (ioctl(mfd, MCGETA, &mmode) == -1) {
perror("MCGETA:");
exit(1);
}
mmode &= ~(MDTR | MRTS);
if (ioctl(mfd, MCSETAF, &mmode) == -1) {
perror("MCSETAF:");
exit(1);
}
#endif
close(mfd);
}
void h_signal()
{
signal(SIGINT, SIG_IGN);
CloseDevice();
(void) fprintf(stderr,"\n");
exit(-1);
}
void change_baud_code(b)
int b;
{
sleep(1);
switch(b){
case 7: /* 9600 */
case 9600:
case 5: /* 4800 */
case 4800:
DPRI1("** 9600 baud **\n");
change_baud(B9600);
break;
#if 0
DPRI1("** 4800 baud **\n");
change_baud(B4800);
break;
#endif
case 3: /* 2400 */
case 2400:
DPRI1("** 2400 baud **\n");
change_baud(B2400);
break;
case 1: /* 600 */
case 600:
DPRI1("** 600 baud **\n");
change_baud(B600);
break;
default: /* ??? */
(void) fprintf(stderr,"code [%d] is unknown baud.\n",b);
h_signal();
break;
}
}
int baud_code(b)
int b;
{
int x;
switch (baud) {
case 600:
x = 0x01;
break;
case 2400:
x = 0x03;
break;
case 4800:
x = 0x05;
break;
case 9600:
x = 0x07;
break;
}
return(x);
}
void error_line()
{
(void) fprintf(stderr,"error: line %d.\n",read_line);
exit(-1);
}
void file_get_token(fp,err)
FILE *fp;
int err;
{
UCHAR *p,c;
int done;
/* skip TAB, comment, linefeed */
done = 0;
do {
c = fgetc(fp);
switch(c){
case 0x09:
case 0x0a:
case 0x0d:
break;
#if 0
case '#':
for(;fgetc(fp) != 0x0a && !feof(fp);) {
if (err && feof(fp)) {
error_line();
}
}
break;
#endif
default:
done = 1;
break;
}
} while(done == 0);
p = buf;
if (feof(fp)) {
*p = '\0';
return;
}
done = 0;
/* get one token : delimiter=TAB, linefeed */
do {
*p++ = c;
c = fgetc(fp);
switch (c) {
case 0x09:
done = 1;
break;
case 0x0a:
case 0x0d:
done = 1;
if (err == 1) {
error_line();
}
break;
}
if (err && feof(fp)) {
error_line();
}
} while(done == 0);
*p = '\0';
if(!strcmp((char *) buf,"*NONE*")){
*buf = '\0';
}
}
void read_file(fname)
char *fname;
{
FILE *fp;
if ((fp = fopen(fname,"r")) == NULL){
(void) fprintf(stderr,"Can't open [%s].\n", fname);
exit(1);
}
read_line = 0; /* line num */
read_grp_num = 0;
read_mem_num = 0;
while (!feof(fp)){
(void) file_get_token(fp,0); /* command , ignore error(EOF) */
switch (buf[0]){
case 'N': /* max nums */
file_get_token(fp,1); /* max group,with error */
(void) sscanf((char *) buf,"%d", &max_grp);
file_get_token(fp,2); /* max memory,with error */
(void) sscanf((char *) buf,"%d", &max_mem);
read_line++;
break;
case 'G': /* group name */
file_get_token(fp,1); /* group num,with error */
(void) sscanf((char *) buf,"%d", &file_grp_num[read_grp_num]);
file_get_token(fp,1); /* yomi ,with error */
(void) strcpy((char *) file_grp_yomi[read_grp_num],(char *) buf);
file_get_token(fp,2); /* kanji ,with error */
(void) strcpy((char *) file_grp_kanji[read_grp_num],(char *) buf);
read_grp_num++;
read_line++;
break;
case 'M': /* memory name */
file_get_token(fp,1); /* mamory num,with error */
(void) sscanf((char *) buf,"%d", &file_mem_num[read_mem_num]);
file_get_token(fp,1); /* group num,with error */
(void) sscanf((char *) buf,"%d", &file_mem_grp[read_mem_num]);
file_get_token(fp,1); /* secret */
(void) sscanf((char *) buf,"%d", &file_mem_secret[read_mem_num]);
file_get_token(fp,1); /* yomi ,with error */
(void) strcpy((char *) file_mem_yomi[read_mem_num],(char *) buf);
file_get_token(fp,1); /* kanji ,with error */
(void) strcpy((char *) file_mem_kanji[read_mem_num],(char *) buf);
file_get_token(fp,2); /* phone ,with error */
(void) strcpy((char *) file_mem_phone[read_mem_num], (char *) buf);
read_mem_num++;
read_line++;
break;
}
}
(void) fclose(fp);
}
void RcvSwapNum(p, col, even)
UCHAR *p;
int col,even;
{
UCHAR c1,c2;
int i;
DPRI1("RcvSwapNum:");
for(i=0; i<col - 1; i++){
if (read(mfd, &c1, 1) < 0) {
perror("RcvSwapNum:");
h_signal();
}
if (read(mfd, &c2, 1) < 0) {
perror("RcvSwapNum:");
h_signal();
}
DPRI3(" %02x %02x",c1,c2);
*p++ = rcv_num_tbl[c2];
*p++ = rcv_num_tbl[c1];
}
DPRI1("\n");
*p = '\0';
if (even) {
--p;
*p = '\0';
}
}
void ReceiveMsg(n,d)
int n;
unsigned char d;
{
unsigned char c = 0;
int i=0;
int ok = 0;
DPRI1("recv:");
while(ok == 0){
if (read(mfd, &c, 1) < 0) {
perror("ReceiveMsg:read");
h_signal();
}
DPRI2(" %02x",c);
(void) fflush(stdout);
if (c == d) {
ok = 1;
}
}
i++;
while (i<n || n==0) {
if (read(mfd, &c, 1) < 0) {
perror("ReceiveMsg:read");
h_signal();
}
DPRI2(" %02x",c);
fflush(stdout);
i++;
}
DPRI1("\n");
}
void RcvMsgMask(n,d,mask)
int n;
unsigned char d,mask;
{
unsigned char c = 0;
int i=0;
int ok = 0;
DPRI1("recv:");
while(ok == 0){
if (read(mfd, &c, 1) < 0) {
perror("ReceiveMsg:read");
h_signal();
}
DPRI2(" %02x",c);
(void) fflush(stdout);
if ((c & mask) == (d & mask)) {
ok = 1;
}
}
i++;
while (i<n || n==0) {
if (read(mfd, &c, 1) < 0) {
perror("ReceiveMsg:read");
h_signal();
}
DPRI2(" %02x",c);
fflush(stdout);
i++;
}
DPRI1("\n");
}
void RcvBuf(n)
int n;
{
UCHAR c = 0;
int i=0;
DPRI1("RcvBuf:");
while ((i<n || n==0) && n < BUFSIZE) {
if (read(mfd, &c, 1) < 0) {
perror("RcvBuf:read");
h_signal();
}
DPRI2(" %02x",c);
buf[i] = c;
i++;
}
DPRI1("\n");
}
void RcvBufVerify(n,d)
int n;
UCHAR d;
{
UCHAR c = 0;
int i=0;
int ok = 0;
DPRI1("RcvBufVerify:");
while(ok == 0){
if (read(mfd, &c, 1) < 0) {
perror("RcvBufVerify:read");
h_signal();
}
DPRI2(" %02x",c);
(void) fflush(stdout);
if (c == d) {
ok = 1;
}
}
buf[i] = c;
i++;
while ((i<n || n==0) && n<BUFSIZE) {
if (read(mfd, &c, 1) < 0) {
perror("RcvBufVerify:read");
h_signal();
}
DPRI2(" %02x",c);
buf[i] = c;
i++;
}
DPRI1("\n");
}
/*
* received string = SJIS
*/
void RcvStr(n,str)
int n;
unsigned char *str;
{
unsigned char c1 = 0, c2 = 0;
unsigned char *p = str;
int i=0;
DPRI1("RecvStr:");
while (i<n || n==0) {
if (read(mfd, &c1, 1) < 0) {
perror("RcvStr:read");
h_signal();
}
if (read(mfd, &c2, 1) < 0) {
perror("RcvStr:read");
h_signal();
}
*p = (c1 << 4) | c2;
i++;
DPRI2("%02x ",*p);
p++;
}
*p = '\0';
DPRI1("\n");
}
int RcvShort()
{
unsigned char c1 = 0, c2 = 0;
int ret;
if (read(mfd, &c1, 1) < 0) {
perror("RcvShort:read");
h_signal();
}
if (read(mfd, &c2, 1) < 0) {
perror("RcvShort:read");
h_signal();
}
DPRI3("RcvShort: %02x %02x\n",c1,c2);
ret = (c1 << 8) + c2;
return(ret);
}
int RcvByte()
{
unsigned char c1 = 0, c2 = 0;
int ret;
if (read(mfd, &c1, 1) < 0) {
perror("RcvByte:read");
h_signal();
}
if (read(mfd, &c2, 1) < 0) {
perror("RcvByte:read");
h_signal();
}
DPRI3("RcvByte: %02x %02x\n",c1,c2);
ret = (c1 << 4) + c2;
return(ret);
}
int RcvNumber()
{
unsigned char c1 = 0, c2 = 0;
int ret;
if (read(mfd, &c1, 1) < 0) {
perror("RcvNumber:read");
h_signal();
}
if (read(mfd, &c2, 1) < 0) {
perror("RcvNumber:read");
h_signal();
}
DPRI3("RcvNumber: %02x %02x\n",c1,c2);
if (c1 == 0x08) {
secret = 1;
} else {
secret = 0;
}
ret = c2 * 100 + RcvByte();
return(ret);
}
int RcvStrLen(p)
UCHAR *p;
{
int len;
len = RcvByte();
if (len) {
RcvStr(len, p);
} else {
#if 0
*p = '\0';
#endif
(void)strcpy((char *) p,"*NONE*");
}
return len;
}
void SendStrNum(s)
unsigned char *s;
{
unsigned char *p;
unsigned char c;
DPRI1("sending ");
p = s;
while(*p != '\0') {
if (*p < '0' && *p > '9') {
(void) fprintf(stderr, "SendStrNum:illegal char [%c]\n", *p);
h_signal();
}
c = rev_num_tbl[*p - '0'] + 0x90;
if (write(mfd, &c , 1) < 0) {
perror("SendStrNum:write");
h_signal();
}
DPRI2("%02x ",c);
p++;
}
DPRI1("\n");
}
void SendDial(s)
unsigned char *s;
{
unsigned char c;
SendStrNum(s);
c = 0xaa;
write(mfd, &c, 1);
DPRI2("%02x : done\n",c);
}
void SendSwapNum(s,col)
UCHAR *s;
int col;
{
UCHAR *p, *q;
UCHAR c;
int i;
/* initialize */
for(i=0; i<BUFSIZE; i++){
buf[i] = 0;
}
/* swap */
p = s;
q = buf;
while(*p != '\0') {
*(q+1) = *p++;
if (*p != '\0') {
*q = *p++;
}
q+=2;
}
DPRI1("sendSwapNum:");
p = buf;
i=0;
for(i=0; i<col; i++){
if (!((*p >= '0' && *p <= '9') || (*p >= 'A' && *p <= 'D') ||
(*p == '*') || (*p == '#') || (*p == '\0'))) {
(void) fprintf(stderr, "SendStrNum:illegal char [%c]\n", *p);
h_signal();
}
if (*p == '\0') {
c = 0;
} else if (*p >= 'A' && *p <= 'C') {
c = *p - 'A' + 0x0d;
} else if (*p == 'D') {
c = 0;
} else if (*p == '#') {
c = 0x0c;
} else if (*p == '*') {
c = 0x0b;
} else {
c = rev_num_tbl[*p - '0'];
}
if (write(mfd, &c , 1) < 0) {
perror("SendSwapNum:write");
h_signal();
}
DPRI2("%02x ",c);
p++;
}
DPRI1("\n");
}
void SendHex(h)
int h;
{
unsigned char c;
c = (unsigned char) h;
if (write(mfd, &c , 1) < 0) {
perror("SendHex:write");
h_signal();
}
DPRI2("sendhex:%02x\n",c);
}
void SendShort(s)
unsigned short s;
{
unsigned int i1, i2;
unsigned char c1, c2;
i1 = (s>>8) & 0xff;
i2 = s & 0xff;
c1 = (UCHAR) i1;
c2 = (UCHAR) i2;
if (write(mfd, &c1 , 1) < 0) {
perror("SendShort:write");
h_signal();
}
if (write(mfd, &c2 , 1) < 0) {
perror("SendShort:write");
h_signal();
}
DPRI3("SendShort :%02x %02x\n",c1,c2);
}
void SendByte(s)
UCHAR s;
{
unsigned int i1, i2;
unsigned char c1, c2;
i1 = (s>>4) & 0xf;
i2 = s & 0xf;
c1 = (UCHAR) i1;
c2 = (UCHAR) i2;
if (write(mfd, &c1 , 1) < 0) {
perror("SendByte:write");
h_signal();
}
if (write(mfd, &c2 , 1) < 0) {
perror("SendByte:write");
h_signal();
}
DPRI3("SendByte :%02x %02x\n",c1,c2);
}
void SendNumber(n)
int n;
{
int i1,i2;
i1 = n / 100;
i2 = n - i1*100;
SendByte((UCHAR) i1);
SendByte((UCHAR) i2);
}
void SendNumberSec(n,sec)
int n,sec;
{
int i1,i2;
i1 = n / 100;
i2 = n - i1*100;
SendHex((UCHAR) sec * 0x08);
SendHex((UCHAR) i1);
SendByte((UCHAR) i2);
}
void SendChar(c)
unsigned char c;
{
unsigned char c1, c2;
c1 = (c>>4) & 0xf;
c2 = c & 0xf;
if (write(mfd, &c1 , 1) < 0) {
perror("SendChar:write");
h_signal();
}
if (write(mfd, &c2 , 1) < 0) {
perror("SendChar:write");
h_signal();
}
DPRI3("SendChar :%02x %02x\n",c1,c2);
}
void SendStr(p)
unsigned char *p;
{
SendByte(strlen((char *) p));
while(*p != '\0'){
SendChar(*p++);
}
}
void SendStrN(p,len)
unsigned char *p;
int len;
{
int n;
if (len) {
n = len;
} else {
n = strlen((char *) p);
}
DPRI3("SendStrN:%d,%d\n",len,n);
SendByte(n);
while(n--){
SendChar(*p++);
}
}
void SendStrNoLen(p)
unsigned char *p;
{
/*
SendByte(strlen((char *) p));
*/
while(*p != '\0'){
SendChar(*p++);
}
}
#ifdef HAVE_STDARG_H
void VaSendHex(int h, ...)
#else
void VaSendHex(va_alist)
va_dcl
#endif
{
va_list ap;
unsigned char c;
#ifdef HAVE_STDARG_H
Va_start(ap, h);
#else
int h;
Va_start(ap, h);
h = (int) va_arg(ap, long);
#endif
DPRI1("VaSendHex:");
while (h != (int) EOL) {
c = (unsigned char) h;
if (write(mfd, &c , 1) < 0) {
perror("VaSendHex:write");
h_signal();
}
DPRI2(" %02x",c);
h = (int) va_arg(ap, long);
}
va_end(ap);
DPRI1("\n");
}
#ifdef HAVE_STDARG_H
int VaCompMsg(int n, ...)
#else
int VaCompMsg(va_alist)
va_dcl
#endif
{
va_list ap;
unsigned char c,d;
int ret = 1;
int i = 0;
#ifdef HAVE_STDARG_H
Va_start(ap, n);
#else
int n;
Va_start(ap, n);
n = (int) va_arg(ap, long);
#endif
DPRI1("VaCompMsg:");
while (i < n) {
if (read(mfd, &c, 1) < 0) {
perror("VaCompMsg:read");
h_signal();
}
d = (unsigned char) va_arg(ap, long);
DPRI3(" read[%02x]=%02x?", c, d);
if (c != d) {
ret = 0;
}
i++;
}
va_end(ap);
DPRI1("\n");
return(ret);
}
void SendPasswdSuccess()
{
VaSendHex(0x6c, 0x03, EOL);
}
void SendMaxGroup(cmd, max_mem, max_grp)
int cmd, max_mem, max_grp;
{
DPRI1("SendMaxGroup\n");
VaSendHex(cmd, 0x0d, 0x00, 0x02, EOL);
/*
* 00 00 : NO YOMI & KANJI
* 00 01 : YOMI ONLY
* 00 02 : KANJI ONLY
* 00 03 : YOMI & KANJI
*/
VaSendHex(0x00, 0x07, EOL);
SendNumber(max_mem); /* max memory */
VaSendHex(0x00, 0x07, EOL); /* enable kanji */
SendByte(LEN_MEM_YOMI);
SendByte(LEN_MEM_KANJI);
SendByte(max_grp); /* max group */
SendByte(LEN_GRP_YOMI);
SendByte(LEN_GRP_KANJI);
SendStrNoLen(ID_CELRW);
VaSendHex(0x00, 0x00, 0x00, 0x00, EOL);
}
void SendGroupName(num, yomi, kanji)
int num;
UCHAR *yomi, *kanji;
{
MSG2("sending group #%d\n",num);
VaSendHex(0x6c, 0x0a, EOL);
SendByte(num);
VaSendHex(0x00, 0x01, EOL);
SendStr(yomi);
VaSendHex(0x00, 0x03, EOL);
SendStr(kanji);
}
void SendMemory(num, grp, sec, yomi, kanji, phone)
int num,grp,sec;
UCHAR *yomi, *kanji, *phone;
{
int col;
int i,j;
MSG2("sending memory #%d\n",num);
DPRI4("%s %s %s\n", yomi, kanji, phone);
/*
* send memory dial
*/
if (*phone) {
VaSendHex(0x6c, 0x06, EOL);
SendNumberSec(num,sec);
VaSendHex(0x00, 0x01, EOL);
if (*yomi) {
DPRI3("yomi_len=%d len=%d\n", yomi_len, strlen(yomi));
if (yomi_len && (strlen(yomi)>yomi_len)) {
SendStrN(yomi,yomi_len);
} else {
SendStr(yomi);
}
} else {
VaSendHex(0x00, 0x00, EOL);
}
col = strlen((char *) phone);
i = (col + 1) / 2 +1;
j = (i-1)*2 - col;
SendShort((unsigned short)i);
if (col) {
SendHex(j*8);
SendHex(0x00);
SendSwapNum(phone,(i-1)*2);
}
SendByte(grp);
if (kanjicode) {
VaSendHex(0x00, kanjicode, EOL);
} else {
VaSendHex(0x00, 0x03, EOL);
}
if (*kanji) {
if (kanji_len && (strlen(kanji) > kanji_len)) {
SendStrN(kanji, kanji_len);
} else {
SendStr(kanji);
}
} else {
VaSendHex(0x00, 0x00, EOL);
}
}
}
void SendEndOfGroup()
{
VaSendHex(0x6c, 0x0c, EOL);
}
int SendOneGroup()
{
int ret = 0;
/* skip no_data area */
while(n_grp<read_grp_num &&
*file_grp_yomi[n_grp] == 0 &&
*file_grp_kanji[n_grp] == 0
) {
n_grp++;
}
if (n_grp < read_grp_num) {
SendGroupName(file_grp_num[n_grp],file_grp_yomi[n_grp],file_grp_kanji[n_grp]);
n_grp++;
} else {
SendEndOfGroup();
ret = 1;
}
return ret;
}
#if 0
void SendMultiGroup()
{
int i;
DPRI1("***** send multiple group\n");
for(i=0; i<read_grp_num; i++){
SendGroupName(file_grp_num[i],file_grp_yomi[i],file_grp_kanji[i]);
if (*file_grp_kanji[i]) {
/* recv 64 07 : more group*/
#if 0
ReceiveMsg(2, 0x64);
#endif
RcvBuf(2);
}
}
}
void SendMultiMem()
{
int i;
DPRI1("***** send multiple memory\n");
for(i=0; i<read_mem_num; i++){
SendMemory(file_mem_num[i],file_mem_grp[i],
file_mem_secret[i],
file_mem_yomi[i],file_mem_kanji[i],
file_mem_phone[i]);
if (*file_mem_phone[i]) {
/* recv 64 06 : more memory*/
ReceiveMsg(2, 0x64);
}
}
/*
* send 6c 08 : finish copying
*/
VaSendHex(0x6c, 0x08, EOL);
}
#endif
void SendEndOfMemory()
{
VaSendHex(0x6c, 0x08, EOL);
}
int SendOneMemory()
{
int ret = 0;
/* skip no_data area */
while(n_mem<read_mem_num &&
*file_mem_phone[n_mem] == 0) {
n_mem++;
}
if (n_mem < read_mem_num) {
SendMemory(file_mem_num[n_mem],file_mem_grp[n_mem],
file_mem_secret[n_mem],
file_mem_yomi[n_mem],file_mem_kanji[n_mem],
file_mem_phone[n_mem]);
n_mem++;
} else {
SendEndOfMemory();
ret = 1;
}
return ret;
}
#ifdef HAVE_STDARG_H
void SendAck(int h, ...)
#else
void SendAck(va_alist)
va_dcl
#endif
{
va_list ap;
unsigned char c;
static UCHAR sendbuf[BUFSIZE];
int i = 0, j , differ;
UCHAR *p, *q;
#ifdef HAVE_STDARG_H
Va_start(ap, h);
#else
int h;
Va_start(ap, h);
h = (int) va_arg(ap, long);
#endif
q = sendbuf;
DPRI1("SendAck:");
while (h != (int) EOL) {
c = (unsigned char) h;
*q++ = c;
i++;
if (write(mfd, &c , 1) < 0) {
perror("SendAck:write");
h_signal();
}
DPRI2(" %02x",c);
h = (int) va_arg(ap, long);
}
va_end(ap);
DPRI1("\n");
RcvBuf(i);
differ = 0;
DPRI1("Verify :");
for(j=1, p=buf+1, q=sendbuf+1; j<i; j++, p++, q++){
DPRI2(" %02x",*p);
if (*p != *q) {
differ = 1;
}
}
DPRI1("\n");
if (differ) {
(void) fprintf(stderr,"Ack Error!\n");
h_signal();
}
}
void parse_id(id)
char *id;
{
cel_db_t *p;
p = cel_db;
while(p->id) {
if (!strncmp(id, p->id, strlen(p->id))) {
DPRI2("Identified: %s\n", p->desc);
if (!yomi_len) {
yomi_len = p->yomilen;
}
if (!kanji_len) {
kanji_len = p->kanjilen;
}
if (!ignore_group) {
ignore_group = p->ignoregroup;
}
kanjicode = p->kanjicode;
}
p++;
}
}
void GetMaxNum(cmd,num,grp)
int cmd;
int *num, *grp;
{
int flag;
int len_yomi, len_kanji;
DPRI1("GetMaxNum\n");
ReceiveMsg(4,cmd);
flag = RcvShort();
#ifdef DEBUG
if (flag & 0x0001) {
(void) fprintf(stderr,"YOMI enabled\n");
}
if (flag & 0x0002) {
(void) fprintf(stderr,"KANJI enabled\n");
}
#endif
*num = RcvNumber();
flag = RcvShort();
len_yomi = RcvShort();
len_kanji = RcvShort();
DPRI3("mem: len #yomi=%d #kanji=%d\n", len_yomi, len_kanji);
if (!yomi_len) {
yomi_len = len_yomi;
}
if (!len_kanji) {
kanji_len = len_kanji;
}
*grp = RcvByte();
len_yomi = RcvShort();
len_kanji = RcvShort();
DPRI3("grp: len #yomi=%d #kanji=%d\n", len_yomi, len_kanji);
RcvStr(6, dummy);
RcvBuf(4);
DPRI2("str=[%s]\n",
dummy);
parse_id(dummy);
}
int GetGroup()
{
static char kana[MAX_BYTE], kanji[MAX_BYTE];
int grp_num;
int len;
/*
* send 64 07 : get group
* result
* 6c 0a : group exists
* 6c 0c : group end
*/
VaSendHex(0x64, 0x07, EOL);
#if PORTWAIT
mwait(400);
#endif
if (VaCompMsg(2,0x6c,0x0c)) {
DPRI1("***** group end.\n");
return 0;
}
grp_num = RcvByte();
DPRI2("* group number:%d\n",grp_num);
MSG2("getting group #%d\n",grp_num);
ReceiveMsg(2,0x00);
len = RcvStrLen(kana);
DPRI2("kana=[%s]\n",kana);
ReceiveMsg(2,0x00);
len += RcvStrLen(kanji);
DPRI2("kanji=[%s]\n",kanji);
if (len) {
(void) printf("G\t%d\t%s\t%s\n",
grp_num, kana, kanji);
}
return 1;
}
int GetMemory()
{
static char kana[MAX_BYTE], kanji[MAX_BYTE], phone[MAX_BYTE];
int grp_num;
int mem_num;
int col,even;
/*
* send 64 06 : read memory dial
*/
VaSendHex(0x64, 0x06, EOL);
#if PORTWAIT
mwait(600);
#endif
/*
* 6c 06 : memory exists
* 6c 08 : memory end
*/
if (VaCompMsg(2,0x6c,0x08)) {
DPRI1("***** memory end.\n");
return 0;
}
mem_num = RcvNumber();
DPRI3("* memory number:%d secret=%d\n",mem_num,secret);
MSG2("getting memory #%d\n",mem_num);
ReceiveMsg(2, 0x00);
RcvStrLen(kana);
DPRI2("furigana=[%s]\n",kana);
col = RcvShort();
if (col) {
RcvBuf(2);
even = buf[0];
RcvSwapNum(phone, col, even);
DPRI2("phone=[%s]\n",phone);
} else {
(void) strcpy(phone, "*NONE*");
}
if (!nogroup) {
grp_num = RcvByte();
DPRI2("group number:%d\n",grp_num);
ReceiveMsg(2, 0x00);
RcvStrLen(kanji);
DPRI2("kanji=[%s]\n",kanji);
} else {
RcvBuf(2);
(void) strcpy(kanji, "*NONE*");
}
if (col) {
(void) printf("M\t%d\t%d\t%d\t%s\t%s\t%s\n",
mem_num,grp_num,secret, kana, kanji, phone);
}
return 1;
}
void RecvAck6c()
{
}
void RecvAck64()
{
static UCHAR ackbuf[BUFSIZE];
int i = 0;
RcvBuf(1);
switch(buf[0]){
case 0x01:
switch (kind) {
case KIND_506G:
sleep(1);
break;
}
VaSendHex(0x6c, buf[0], EOL);
break;
case 0x02:
case 0x0e:
ackbuf[i++] = buf[0];
RcvBuf(1);
VaSendHex(0x6c, ackbuf[0], buf[0], EOL);
break;
}
}
void cb_timeout(sig)
int sig;
{
/*
signal(sig,SIG_IGN);
*/
(void) fprintf(stderr,"alarm catch\n");
longjmp(jump_env,1);
}
void set_action()
{
#ifdef HAVE_SIGACTION
struct sigaction new_action;
new_action.sa_handler = cb_timeout;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = SA_NODEFER;
(void) sigaction(SIGALRM, &new_action, NULL);
#else
signal(SIGALRM,cb_timeout);
#endif
}
void ign_action()
{
#ifdef HAVE_SIGACTIOON
struct sigaction new_action;
new_action.sa_handler = SIG_IGN;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = SA_NODEFER;
(void) sigaction(SIGALRM, &new_action, NULL);
#else
signal(SIGALRM,SIG_IGN);
#endif
}
void RecvAck()
{
int done = 0;
while(!done){
RcvBuf(1);
switch(buf[0]){
case 0x6c: /* extend mode 1 */
RecvAck6c();
done=1;
break;
case 0x64: /* extend mode 2 */
RecvAck64();
done=1;
break;
case 0x60:
ign_action();
VaSendHex(0x61, EOL);
SendStrNoLen(ID_CELRW);
SendStrNoLen(" ");
RcvBuf(2); /* 64 08 */
VaSendHex(0x6c, 0x0b, 0x00, 0x00, EOL);
RcvBuf(4); /* 6c 0c 64 05 */
VaSendHex(0x6c, 0x05, 0x00, 0x03, 0x00, 0x00, EOL);
nogroup=1;
done=1;
break;
}
}
}
int SendMemoryAck(code)
int code;
{
int ret = 1;
unsigned char c;
if (read(mfd, &c, 1) < 0) {
perror("SendMemoryAck:read");
h_signal();
}
if (c != 0x64) {
ret = 0;
}
DPRI((stderr, "required:64, received:%02x\n", c));
if (read(mfd, &c, 1) < 0) {
perror("SendMemoryAck:read");
h_signal();
}
if (c != code && c != 0x0b && c != 0x00) { /* ok nor incomplete */
ret = 0;
}
DPRI3("required:%02x, received:%02x\n", code, c);
return(ret);
}
void StoreCellular()
{
int temp_mem = 999, temp_grp = 99;
int x;
int eog;
MSG1("establishing connection ...");
/* make connection */
SendHex(0xa8);
sleep(2);
SendHex(0xa8);
#if PORTWAIT
mwait(200);
#endif
/* recv 64 01 */
/* send 6c 01 */
RecvAck();
MSG1("done\n");
sleep(2);
#if 0
/* recv a3: request passcode */
switch (kind) {
case KIND_506G:
/* recv 64 01 */
ReceiveMsg(2,0x64);
break;
default:
RcvMsgMask(1,0xa3,0x7f);
break;
}
#else
ALARMW {
RcvMsgMask(1,0xa3,0x7f);
}
#endif
/* enter passcode on cellular */
(void) fprintf(stderr,"Input your pass code into cellular\n");
/*
sleep(2);
*/
/* recv 64 02 xx: set baud rate */
/* send 6c 02 xx: set baud rate */
RcvBufVerify(3,0x64);
/* request speed */
if (force_baud) {
x = baud_code(baud);
} else {
x = buf[2];
}
VaSendHex(0x6c, 0x02, x, EOL);
/* change baud */
change_baud_code(x);
/* any 4 digit */
(void) fprintf(stderr,"Input any 4 digit into cellular\n");
/* recv: 64 03 9a 9a 9a 9a 64 04 */
RcvBuf(8);
/* send: 6c 03 */
SendPasswdSuccess();
/* recv 64 0e 02 & ack*/
/* send 6c 0e 02 */
ALARMW {
RecvAck();
} ELSE {
ALARMW {
/* for HD-50S */
VaSendHex(0x64, 0x0e, 0x03, 0x01, 0x00, EOL);
ReceiveMsg(5,0x6c);
} ELSE {
/* for J-PE02 */
RecvAck();
}
}
/* send max grp and num */
if (!nogroup) {
/* group num and memory num to send are identical with that of read */
ALARMW {
GetMaxNum(0x64, &temp_mem, &temp_grp);
SendMaxGroup(0x6c, temp_mem, temp_grp);
}
ign_action();
DPRI3("cel: grp=%d, mem=%d\n", temp_grp, temp_mem);
#if 0
/* recv 64 07 */
RcvBuf(2);
/* send group name */
SendMultiGroup();
SendEndOfGroup();
#else
if (!ignore_group) {
/* send multiple group */
eog = 0;
while(eog == 0){
/* 64 07 : get group */
if (!SendMemoryAck(0x07)) {
eog=1;
} else {
eog = SendOneGroup();
}
}
} else {
/* recv 64 07 */
RcvBuf(2);
SendEndOfGroup();
}
#endif
}
#if 0
/* send memory */
/* recv: 64 06 */
RcvBuf(2);
SendMultiMem();
#else
/* send multiple memory */
eog = 0;
while(eog == 0){
/* 64 06 : get memory */
if (!SendMemoryAck(0x06)) {
eog=1;
} else {
eog = SendOneMemory();
}
}
#endif
sleep(2);
/* memory copy done */
VaSendHex(0xa8, EOL);
(void) fprintf(stderr,"send memory done.\n");
}
void ReadCellular(passwd)
char *passwd;
{
int x;
/* establish connection */
MSG1("establishing connection ...");
SendHex(0xa8);
sleep(2);
SendHex(0xa8);
/* recv 64 01 */
ReceiveMsg(2,0x64);
MSG1("done\n");
/* send 6c 01 */
VaSendHex(0x6c, 0x01, EOL);
/*
sleep(2);
*/
#if 0
/* recv a3: request passcode */
switch (kind) {
case KIND_506G:
/* recv 64 01 */
ReceiveMsg(2,0x64);
break;
default:
RcvMsgMask(1,0xa3,0x7f);
break;
}
#else
ALARMW {
RcvMsgMask(1,0xa3,0x7f);
}
#endif
sleep(2);
/* request speed */
/* send 64 02 xx */
/* recv 6c 02 xx */
x = baud_code(baud);
VaSendHex(0x64, 0x02, x, EOL);
#if PORTWAIT
mwait(200);
#endif
RcvBufVerify(3,0x6c);
/* change baud */
change_baud_code(buf[2]);
sleep(2);
/* send passwd */
MSG1("sending password\n");
VaSendHex(0x64, 0x03, EOL);
SendStrNum(passwd);
VaSendHex(0x64, 0x04, EOL);
#if PORTWAIT
mwait(200);
#endif
/*
* recv 6c 03 => success
* recv 6c 04 => fail
*/
if (VaCompMsg(2,0x6c,0x03)) {
(void) fprintf(stderr,"passwd OK\n");
} else {
(void) fprintf(stderr,"invalid passwd\n");
h_signal();
}
/*
* read group
* send 64 0e 02
* recv 6c 0e 02
*/
VaSendHex(0x64, 0x0e, 0x02, EOL);
#if PORTWAIT
mwait(200);
#endif
/* for HD-50S hack */
ALARMW {
/* for HD-50S hack */
/*
ReceiveMsg(3,0x6c);
*/
RcvBuf(1);
switch(buf[0]){
case 0x6c:
RcvBuf(2);
break;
case 0x64:
/* for HD-50S */
RcvBuf(4);
VaSendHex(0x6c, buf[0], buf[1], buf[2], buf[3], EOL);
break;
}
} ELSE {
/* DP144 */
VaSendHex(0x60, EOL);
RcvBuf(1);
RcvStr(8, dummy);
DPRI((stderr,"str=[%s]\n",dummy));
ALARMW {
RcvStr(8, dummy);
DPRI((stderr,"additional str=[%s]\n",dummy));
} ELSE {
}
VaSendHex(0x64, 0x08, EOL);
RcvBuf(4); /* 6c 0b 00 00 */
VaSendHex(0x6c, 0x0c, 0x64, 0x05, EOL);
RcvBuf(6); /* 6c 05 00 03 00 00 */
nogroup = 1;
}
/*
* send max group num
* send 64 0d
*/
SendMaxGroup(0x64, 999, 99);
#if PORTWAIT
mwait(1000);
#endif
ALARMW {
GetMaxNum(0x6c, &max_mem, &max_grp);
DPRI3("max_mem=%d max_grp=%d\n",
max_mem, max_grp);
} ELSE {
max_mem = 999;
max_grp = 99;
}
ign_action();
(void) printf("N\t%d\t%d\n",
max_mem, max_grp);
/* get groups */
if (!nogroup) {
while(GetGroup());
}
/* get memory */
while(GetMemory());
}
UCHAR *input_passwd()
{
TERMIO sg0, sg1;
int i;
UCHAR c;
static UCHAR b[10];
Tcgeta(0, &sg0);
Tcgeta(0, &sg1);
sg1.c_lflag &= ~(ECHO|ICANON);
sg1.c_lflag |= ISIG;
Tcseta(0, &sg1);
(void) fprintf(stderr,"input passwd : ");
(void) fflush(stderr);
for(i=0; i<4; i++){
c = (UCHAR) getchar();
(void) fprintf(stderr,"*");
(void) fflush(stderr);
b[i] = c;
}
b[4] = '\0';
(void) fprintf(stderr,"\n");
Tcseta(0, &sg0);
return(b);
}
void ListKind()
{
int i;
(void) fprintf(stderr,"Supported non-generic cellulars are:\n");
for(i=0; i<KIND_NUM; i++){
(void) fprintf(stderr,"\t%s\n",cel_kind[i].str);
}
}
void Usage(name)
char *name;
{
(void) fprintf(stderr,"\n\
usage:\n\
%s [-s file][-b baud][-d dev][-k kind][-p][-num password][-v][-help]\n\
\n\
-s file : store file data to cellular [default is read]\n\
-b baud : baud rate (600,2400,9600) [default:9600 bps]\n\
-d dev : serial device [default: /dev/ttyS0]\n\
-k kind : kind of cellular\n\
-p : use default password\n\
-num pw : password for cellular [NOT RECOMMEND]\n\
-yomilen len : restrict yomi length\n\
-kanjilen len : restrict kanji length\n\
-nogroup: don't write group data\n\
-v : display version\n\
-V : not verbose\n\
-help : display this message\n\
\n\
",name);
ListKind();
}
void SwitchMode(mode,passwd)
int mode;
UCHAR *passwd;
{
switch (mode) {
case MODE_STORE:
if (read_mem_num == 0) {
(void) fprintf(stderr, "You must read file.\n");
exit(-1);
}
StoreCellular();
break;
case MODE_READ:
if (passwd == NULL) {
passwd = input_passwd();
}
ReadCellular(passwd);
break;
}
}
#ifndef EXP
#define EXP
#else
#include "exp.c"
#endif
int main(argc,argv)
int argc;
char **argv;
{
int mode;
UCHAR *passwd = NULL;
char *appname = argv[0];
int i;
int valid;
signal(SIGINT, h_signal);
mode = MODE_READ;
baud = 9600;
/***** analyze command line *****/
SWITCH_OPT
EXP
CASE_OPT("-s"){
mode = MODE_STORE;
ADVANCE_OPT;
read_file(CURRENT_OPT);
}
CASE_OPT("-d"){
ADVANCE_OPT;
device = CURRENT_OPT;
}
CASE_OPT("-num"){
ADVANCE_OPT;
passwd = (UCHAR *) CURRENT_OPT;
}
CASE_OPT("-yomilen"){
ADVANCE_OPT;
(void) sscanf(CURRENT_OPT, "%d", &yomi_len);
}
CASE_OPT("-kanjilen"){
ADVANCE_OPT;
(void) sscanf(CURRENT_OPT, "%d", &kanji_len);
}
CASE_OPT("-nogroup"){
ignore_group = 1;
}
CASE_OPT("-p"){
passwd = (UCHAR *) PASSCODE;
}
CASE_OPT("-kanjicode"){
ADVANCE_OPT;
(void) sscanf(CURRENT_OPT, "%d", &kanjicode);
}
CASE_OPT("-k"){
ADVANCE_OPT;
for(i=0; i<KIND_NUM; i++){
if (!strcmp(CURRENT_OPT, cel_kind[i].str)){
kind = cel_kind[i].num;
}
}
if (kind == 0) {
(void) fprintf(stderr,"Unknown kind of cellular [%s].\n",
CURRENT_OPT);
ListKind();
exit(-1);
}
}
CASE_OPT("-b"){
ADVANCE_OPT;
(void) sscanf(CURRENT_OPT, "%d", &baud);
force_baud = baud;
valid = 0;
for(i=0; i<NUM_BAUD; i++){
if (valid_baud[i] == baud) {
valid = 1;
}
}
if (!valid) {
(void) fprintf(stderr,"Invalid baud rate %d.\n", baud);
(void) fprintf(stderr,"Valid baud rates are\n");
for(i=0; i<NUM_BAUD; i++){
(void) fprintf(stderr,"%d, ", valid_baud[i]);
}
(void) fprintf(stderr,"\n");
exit(1);
}
}
CASE_OPT("-v"){
(void) fprintf(stderr,"%s version %s\n",
appname,VERSION);
exit(0);
}
CASE_OPT("-V"){
verbose = 0;
}
ELSE_OPT {
Usage(appname);
exit(1);
}
END_OPT;
OpenDevice();
SwitchMode(mode,passwd);
/* reset DoCoMo */
VaSendHex (0x1f, 0x07, 0x0d, EOL);
CloseDevice();
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1