[comp.sys.encore] Annex mapped port problem

peiffer@umn-cs.cs.umn.edu (Tim J. Peiffer) (02/09/90)

I am not sure whether Encore or Xylogics will comment on this, but here
goes..  Direct mapped socket programming on the AnnexII terminal server
does not function as advertised.  I am trying to query a serial device
hooked up to a serial port.  The serial device responds to a data stream
exactly as I expect, but the annex either loses or ignores characters.
Does anyone have a comment or a pointer on how to do this right?

I am using a Xylogics varient of the AnnexII, and have tried direct
mapped serial line access in the 500x and 700x range.  Tapping of
the port in question shows that the serial device is responding to
the query, and issuing a correct response.  Using telnet options,
it shows that the annex is not forwarding all data.  This conclusion
is backed up by a sniffer.  A copy of the code fragment, telnet, tap, 
and sniffer output are included for reference.

I have reloaded from an MX R4.1 host with similar results.  

Tim Peiffer			peiffer@cs.umn.edu	or
Computer Science Dept		...!rutgers!umn-cs!peiffer
University of Minnesota
MPLS, MN	55455

-------------------------------------------------------< Port settings
annex ts18 port 2:
                       speed: 2400
                   data_bits: 7
                   stop_bits: 1
                      parity: none
                 imask_7bits: Y
               control_lines: none
                        type: hardwired
                        mode: adaptive
---------------------------------------------------------< Telnet
telnet> display
will flush output when sending interrupt characters.
won't send interrupt characters in urgent mode.
won't map carriage return on output.
will recognize certain control characters.
will turn on socket level debugging.
will print hexadecimal representation of network traffic.
won't show option processing.
U
> 0x0   550d0a
< 0x0   007f7f
R
> 0x0   520d0a
< 0x0   00
< 0x0   7f7f
---------------------------------------------------------< Tap
annex# tap -skvx 2
Tapped into port 2.
To disconnect the tap, break to the CLI prompt and kill this job.
55 0d <break> <end break> <00> <62> <0c> <74> <0b> <73> <7f> <75> <7f> 
52 0d <01> <62> <0c> <74> <0b> <03> <7d> <05> <7d> <break> <end break>
<00> <62> <0c> <74> <0b> <73> <7f> <75> <7f>
---------------------------------------------------------< Sniffer

- - - - - - - - - - - - - - - - Frame 149 - - - - - - - - - - - - - - - - -
SUMMARY  Delta T     Destination   Source        Summary
   149            ts18         Sequnt0012EB  Telnet C PORT=53613 U
Telnet:----- Telnet data -----
Telnet:U
- - - - - - - - - - - - - - - - Frame 152 - - - - - - - - - - - - - - - - -
   152    0.0557  Sequnt0012EB ts18          Telnet R PORT=53613 <7F>
Telnet:<7F>
- - - - - - - - - - - - - - - - Frame 155 - - - - - - - - - - - - - - - - -
   155    0.0112  Sequnt0012EB ts18          Telnet R PORT=53613 <7F>
Telnet:<7F>
---------------------------------------------------------< code frag

/*
 * MODULE: ipc.c
 * This file should contain all of the subroutines required to query a raw
 * ipc sockets.
 * query():  
 *	Creates a socket and initiates a connection with a socket on 
 *	Annex.  The query message is sent over the connection, and then 
 *	waits for a response.  The connection should be done with raw-mapped
 *	connections (port 70xx) (or port 50xx)
 *	uses:	socket(), gethostbyname(), htons(), connect(), fdopen(),
 *		close(), malloc(), read(), isprint(),
 *		ParseWords()
 */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>	/* not needed for read, but lint fails without */
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <curses.h>
#include "error.h"
#include "dpt.h"

extern void *malloc();
extern int XLOG_INFO;

query(win)
WINDOW *win;		/* curses stuff deleted */
{
	int i,j,sock; /* sockets and run of the mill integers */
	int cc,read(), recv(), bind();		/* sys calls */
	struct hostent *hp, *gethostbyname();
	struct in_addr in;
	struct sockaddr_in server;
	int userint();				/* user functions */
	char *ntoa();
	t_modem *r, *ParseWords();
	register FILE *infile, *outfile;
	char *host;
	int c[9];				/* modem return */

	char *DATA = "U";			/* update command */
	int seq;
	extern int Debug;


	/*create socket */
	if ((sock = socket( AF_INET, SOCK_STREAM, 0)) < 0){
		logerr(XLOG_INFO, 
			"icp.c query: cant get socket\n");
		exit(1);
	}

	/* find IP address of SOCK_HOST */
	server.sin_family = AF_INET;
	if((hp = gethostbyname(SOCK_HOST)) == NULL){
		logerr(XLOG_INFO, 
			"ipc.c query: host unknown\n");
		exit(1);
	}

	host = hp->h_name;		/* this is the official name 	*/
	bcopy (hp->h_addr, (char *)&server.sin_addr.s_addr, hp->h_length);
	server.sin_port = htons(SOCK_NUM);

	/* Connect socket using name SOCK_HOST. */
	if ((i=connect(sock, &server, sizeof( server ))) < 0){
		logerr_die(XLOG_INFO, 
			"ipc.c query: connecting stream socket");
		j = close(sock);
		exit(1);
	}

	if (( infile = fdopen(sock, "r")) == NULL) {
		perror("fdopen");
		j = close(sock);
		exit(1);
	}

	if ((cc = send(sock, DATA, 1, 0)) < 0){
		logerr_die(XLOG_INFO,
			"ipc query: failed to send to socket\n");
		j = close(sock);
		exit(1);
	}

	for( i = 0; i<9;i++) c[i] = 0;
	j = fflush(infile);
	seq = 0;

	/* we are connected to the socket and an initial update
	 * requested.  Forever get data and process...
	 */

	for(;;){
                for ( i = 0; i < 9; i++)
                         (c[i] = getc(infile));
                j = fflush(infile);
		seq++;
		if (Debug >= 3){
		  log(XLOG_INFO, "got another packet seq# %d", seq);
		  j = fprintf(stderr,"Data returned from modem ");
		  for(i = 1; i <= 9; i++ ){
			if( c[i] < 16) fprintf(stderr,"0x0%x ", c[i]);
			else fprintf(stderr,"0x%x ", c[i]);
			}
		  fprintf(stderr,"\n");
		}
		r = ParseWords(c);
		if (Debug >= 3){
			log(XLOG_INFO,"r->config = '%s'", r->config);
			log(XLOG_INFO,"r->optics = '%s'", r->optics);
			log(XLOG_INFO,"r->fault = '%s'", r->fault);
			log(XLOG_INFO,"r->R1L_RAC = '%d'", r->R1L_RAC);
			log(XLOG_INFO,"r->R2L_RAC = '%d'", r->R2L_RAC);
			log(XLOG_INFO,"r->R1R_RAC = '%d'", r->R1R_RAC);
			log(XLOG_INFO,"r->R2R_RAC = '%d'", r->R2R_RAC);
		}
		
	      }
}