You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

163 lines
4.8 KiB

/**********
Permit to use it as your wish.
Author: 2007 Gong Ding, gdiso@ustc.edu
University of Science and Technology of China
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "ngspice/smpdefs.h"
#include "ndevdefs.h"
#include "ngspice/numconst.h"
#include "ngspice/numenum.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#define TSCALLOC(var, size, type)\
if (size && (var =(type *)calloc(1, (unsigned)(size)*sizeof(type))) == NULL) {\
return(E_NOMEM);\
}
int NDEVmodelConnect(NDEVmodel *inModel);
int NDEVsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
/*
* load the structure with those pointers needed later for fast matrix
* loading
*/
{
NDEVmodel *model = (NDEVmodel *)inModel;
NDEVinstance *here;
int i,j;
CKTnode *node;
NG_IGNORE(ckt);
NG_IGNORE(states);
/* loop through all the ndev models */
for( ; model != NULL; model = NDEVnextModel(model)) {
/* connect to remote device simulator */
if(NDEVmodelConnect(model)) return E_PRIVATE;
/* loop through all the instances of the model */
for (here = NDEVinstances(model); here != NULL ;
here=NDEVnextInstance(here)) {
here->Ndevinfo.term = here->term;
strncpy(here->Ndevinfo.NDEVname, here->gen.GENname, 32);
send(model->sock,&(here->Ndevinfo),sizeof(here->Ndevinfo),0);
/* macro to make elements with built in test for out of memory */
#define TSTALLOC(ptr,first,second) \
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
return(E_NOMEM);\
} } while(0)
for(i=0;i<here->term;i++)
for(j=0;j<here->term;j++)
{
TSTALLOC(mat_pointer[i*here->term+j], pin[i], pin[j]);
}
for(i=0;i<here->term;i++)
{
node = here->node[i];
here->PINinfos[i].pin=node->number;
strncpy(here->PINinfos[i].name,here->bname[i],32);
here->PINinfos[i].V = 0.0;
send(model->sock,&here->PINinfos[i],sizeof(here->PINinfos[i]),0);
}
}
}
return(OK);
}
int NDEVmodelConnect(NDEVmodel *inModel)
{
NDEVmodel *model = inModel;
struct hostent *hostlist; /* List of hosts returned by gethostbyname. */
char dotted_ip[15]; /* Buffer for converting
the resolved address to
a readable format. */
struct sockaddr_in sa; /* Connection address. */
char *buf = TMALLOC(char, 128);
/* Look up the hostname with DNS. gethostbyname
(at least most UNIX versions of it) properly
handles dotted IP addresses as well as hostnames. */
hostlist = gethostbyname(model->host);
if (hostlist == NULL)
{
fprintf(stderr,"NDEV: Unable to resolve host %s.\n", model->host);
return E_PRIVATE;
}
/* Good, we have an address. However, some sites
are moving over to IPv6 (the newer version of
IP), and we're not ready for it (since it uses
a new address format). It's a good idea to check
for this. */
if (hostlist->h_addrtype != AF_INET)
{
fprintf(stderr,"NDEV: Host %s doesn't seem to be an IPv4 address.\n",model->host);
return E_PRIVATE;
}
/* inet_ntop converts a 32-bit IP address to
the dotted string notation (suitable for printing).
hostlist->h_addr_list is an array of possible addresses
(in case a name resolves to more than on IP). In most
cases we just want the first. */
inet_ntop(AF_INET, hostlist->h_addr_list[0], dotted_ip, 15);
/* Create a socket for the connection. */
model->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if (model->sock < 0)
{
fprintf(stderr, "NDEV: Unable to create a socket %s.\n", strerror(errno));
return E_PRIVATE;
}
/* Fill in the sockaddr_in structure. The address is
already in network byte order (from the gethostbyname
call). We need to convert the port number with the htons
macro. Before we do anything else, we'll zero out the
entire structure. */
memset(&sa, 0, sizeof(struct sockaddr_in));
sa.sin_port = htons(model->port);
/* The IP address was returned as a char * for
various reasons.
Just memcpy it into the sockaddr_in structure. */
memcpy(&sa.sin_addr, hostlist->h_addr_list[0],
(size_t) hostlist->h_length);
/* This is an Internet socket. */
sa.sin_family = AF_INET;
/* Connect! */
if (connect(model->sock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
{
fprintf(stderr, "NDEV: Unable to connect %s\n",strerror(errno));
return E_PRIVATE;
}
sprintf(buf, NG_QUERY);
send(model->sock, buf, 128, 0);
if(recv(model->sock, buf, 128, MSG_WAITALL) < 128)
{
fprintf(stderr, "NDEV: Remote answer error. %s\n",strerror(errno));
return E_PRIVATE;
}
if(strncmp(buf, NDEV_REPLY, sizeof(NDEV_REPLY)))
{
fprintf(stderr, "NDEV: Remote answer error. %s\n", buf);
return E_PRIVATE;
}
free(buf);
return (OK);
}