// 新設 : 1999 Jul 9th // 動作 : MultiSocket で管理している Connection 構造体を参照する // 入力 : *msocket : 対象のマルチソケット構造体 // 入力 : no : 対象の Connection 構造体の番号 Connection *MultiSocket::GetConnection (int no) { if (no<0 || no>=MAX_MULTI_SOCKET) { tl_warning ("No.%d is too large. MAX is %d!", no, MAX_MULTI_SOCKET); return NULL; } if (!(connection[no])) { tl_warning ("Target connection Pointer is NULL!"); return NULL; } return connection[no]; }
/*----------------------------------------------------------------------------*/ int Threshold::SaveToFile (char *filename) { int i, j; FILE *fp; if (debug) tl_message ("Start"); if ((fp = fopen(filename, "w"))==NULL) { tl_warning ("Cannot open the file : %s", filename); return FALSE; } if (debug) tl_message ("Filename : %s", filename); fprintf( fp, "# Number of State\n%d\n", number_of_state ); fprintf( fp, "# Parameter Dimension\n%d\n", dimension ); if (dimension==2 ) fprintf( fp, "# State No.&Value min max mean\tmin max mean\n"); else fprintf( fp, "# State No.&Value min max mean\n"); for (i=0; i<number_of_state; i++) { fprintf (fp, "%d\t%d\t", i, segment_seq[i].DiscreteValue()); for (j=0; j<dimension; j++) { fprintf (fp, "%g %g %g", segment_seq[i].MinValue(j), segment_seq[i].MaxValue(j), segment_seq[i].Mean(j) ); if (j!=dimension-1) fprintf (fp, "\t"); } fprintf (fp, "\n"); } fclose(fp); if (debug) tl_message ("End"); return TRUE; }
// Added : : 1999 Feb 17th // Memo : To establish a connection to Multi-Server // Input : *serverhost : hostname of server // Input : port : port no. int Connection::MultiClientOpen( char *serverhost,int port ) { char com[10]; if (SocketClientOpen( serverhost, port )==CONNECTION_FAIL) { perror( "<MultiClinetOpen> socket client open"); return CONNECTION_FAIL; } // Receiving BUSY / O.K. Receive( CONNECTION_STRING, com ); if (!strcmp(com, CONNECTION_BUSY)) { Close(); tl_message ("Server is too busy, connection refused"); return CONNECTION_FAIL; } else if( strcmp(com, CONNECTION_OK) ) { tl_warning ("!SERIOUS WARNING! Server ought to send BUSY or O.K. But {%s} came.", com); MultiClientClose(); return CONNECTION_FAIL; } // Send a name to server after connection Send (CONNECTION_STRING, name); return CONNECTION_SUCCESS; }
// 変更 : 1999 Apr 24th : AutoReport の廃止 // Added : : 1999 Feb 17th // 動作 : クライアントとして Socket を普通に作る // 注意 : Open & MultiClientOpen から同時使用されている int Connection::SocketClientOpen(char *serverhost, int port_01) { struct hostent *servhost; struct sockaddr_in server; int s, debug=1; if(debug) tl_message ("%s: SocketClient %s:%d", GetName(), serverhost, port_01); port = port_01; servhost = gethostbyname(serverhost); bzero( (char *)&server, sizeof(server) ); server.sin_family = AF_INET; server.sin_port = htons(port); bcopy( servhost ->h_addr, (char *)&server.sin_addr,servhost->h_length); s = socket( AF_INET, SOCK_STREAM, 0 ); connect( s, (const struct sockaddr *)&server, sizeof(server) ); fd_read = s; fd_write = s; fp_read = fdopen( fd_read, "r+" ); // Read&Write fp_write = fp_read; if( fd_read ==FALSE || fp_read ==NULL || fd_write==FALSE || fp_write==NULL ) { tl_warning ("reverse Error !!"); return CONNECTION_FAIL; } return CONNECTION_SUCCESS; }
/*----------------------------------------------------------------------------*/ int Threshold::QueryDiscreteValue (double continuous_value) { if (dimension!=1) { tl_warning ("dimension is not 1"); return FALSE; } return Query1D (continuous_value); }
/*----------------------------------------------------------------------------*/ int Threshold::QueryDiscreteValue (vector<double> vec) { if (vec.size() == 1 || vec.size() > 2) { tl_warning ("dimension is not 2"); return FALSE; } return Query2D (vec[0], vec[1]); }
/*----------------------------------------------------------------------------*/ vector<double> Threshold::TypicalData (int state_val, int *data) { for (int i=0; i<number_of_state; i++) { if (segment_seq[i].DiscreteValue() == state_val) return segment_seq[i].MeanVector(); } tl_warning ("No such state : No.%d in {%s}", state_val, label.c_str()); return segment_seq[0].MeanVector(); }
///////////////////////////////////////////////////////////////////////// // Added : 1999 Jun 16th : 今までなかったのか !? // 動作 : Connection 型の構造体を Destructor する Connection::~Connection() //NOT A DESTRUCTOR { // 通信路が開いているかどうか,チェック.開いていたら閉じる if( fsync( FdWrite() )==0 ) { tl_warning ("FD haven't closed yet!!"); Close(); } // delete; // return TL_SUCCESS; }
// 変更 : 1999 Apr 28th : サーバからは接続を切らない // 新設 : 1999 Feb 16th // 動作 : マルチアクセスのサーバで動的に接続を切る int MultiSocket::Close(int no) { if (no<0 || no>=MAX_MULTI_SOCKET) { tl_warning ("No such no.%d", no); return FALSE; } connection[no] = NULL; return TRUE; }
/*----------------------------------------------------------------------------*/ int Threshold::SetValue (int target_index, double max_v, double min_v, int discrete_state_value) { if (target_index<0 || target_index > number_of_state) { tl_warning ("No such state No.%d", target_index); return FALSE; } segment_seq[target_index].SetMinMaxValue (0, min_v, max_v); segment_seq[target_index].DiscreteValue (discrete_state_value); return TRUE; }
/*----------------------------------------------------------------------------*/ int Threshold::Query1D (double value) { int i; if (debug) tl_message ("thre=%s , value = %g", label.c_str(), value ); for (i=0; i<number_of_state; i++) if (segment_seq[i].MaxValue(0) >= value && segment_seq[i].MinValue(0) <= value) { if (debug) tl_message ("result = %d", i); return segment_seq[i].DiscreteValue(); } if (value==VALUE_UNOBSERVED) return VALUE_UNOBSERVED; tl_warning ("No such category (value = %g) in {%s}", value, label.c_str()); return -1; }
int SegmentState::SetMinMaxValue (int dim, double min_value, double max_value) { if (dim<0 || dim>=(int)(max.size())) { tl_warning ("input dimension <%d> is wrong parameter", dim); return FALSE; } else if (1) { tl_message ("set min=%g, max=%g as %d-th dimension", min_value, max_value, dim); } min[dim] = min_value; max[dim] = max_value; tl_message ("end of function"); return 1; }
/*-------------------------------------------------------------------------*/ int Connection::Send_Integer (gpointer data) { int ret, fd, value; fd = FdWrite(); value = *((int *)data); ret = my_send(fd, &value, sizeof(int)); fsync(fd); if (ret!=sizeof(int)) { tl_warning ("Fd<%d>: Cannot write (%d)", fd, ret); return FALSE; } return TRUE; }
/*----------------------------------------------------------------------------*/ int Threshold::Query2D (double value1, double value2) { int i; for (i=0; i<number_of_state; i++) { SegmentState seg = segment_seq[i]; if (seg.MaxValue(0) >= value1 && seg.MinValue(0) <= value1 && seg.MaxValue(1) >= value2 && seg.MinValue(1) <=value2) { if (debug) tl_message ("(%g, %g) --> %d", value1, value2, i); return seg.DiscreteValue(); } } if (value1==VALUE_UNOBSERVED) return VALUE_UNOBSERVED; tl_warning ("No such category (value = %g, %g) in {%s}", value1, value2, label.c_str()); return FALSE; }
/*----------------------------------------------------------------------------*/ int Threshold::LoadFromFile (char *filename) { FILE *fp; char line[MAX_STRING], *charp; int i, j, tmp, state_no, min, max, mean, ret; if (debug) tl_message ("File : %s", filename); // if the suffix is not ".thd", it becomes to be error if (!tl_strmember (filename, ".thd")) { tl_warning ("This file {%s} doesn't include .thd suffix!", filename); return FALSE; } // Cehck the existance of the file if (( fp = fopen( filename, "r"))==NULL) { tl_warning ("No such file {%s}", filename); // If the previous file is not 'free-ed', the return might be NULL return FALSE; } label = filename; fgets (line, MAX_STRING, fp); if (!tl_strmember( line, "# Number of State")) { tl_message ("syntax error in %s, Description Error [%s]", filename, line); return FALSE; } fgets (line, MAX_STRING, fp); sscanf( line, "%d", &tmp ); if (tmp <= 0) { tl_warning ("Syntax error: number of State = %d", tmp); return FALSE; } number_of_state = tmp; segment_seq.resize(number_of_state); // Reading the number of dimension of raw data fgets (line, MAX_STRING, fp); if (!tl_strmember( line, "Parameter Dimension")) { tl_message ("Description Error %s", line ); return FALSE; } fgets (line, MAX_STRING, fp); sscanf (line, "%d", &tmp); if (tmp <= 0) { tl_warning ("Syntax Error: Dimension = %d", tmp); return FALSE; } dimension = tmp; // reading each line after skipping one line fgets (line, MAX_STRING, fp); for (i=0; i<number_of_state; i++) { // loop for number of states fgets (line, MAX_STRING, fp); charp = line; // Reading index of the target segment ret = sscanf_int_with_seeking (&charp, &state_no); if (state_no < 0) { tl_warning ("State No. is wrong %d", state_no); return FALSE; } // Reading value for the segment ret = sscanf_int_with_seeking( &charp, &tmp); if (tmp < 0) { tl_warning ("Discrete Value is wrong %d", tmp); return FALSE; } segment_seq[state_no].DiscreteValue (tmp); // Reading Min and Max value for j-th dimension of the segment for (j=0; j<dimension; j++) { ret = sscanf_int_with_seeking (&charp, &min); if (debug) tl_message("read min value = %d", min); ret = sscanf_int_with_seeking (&charp, &max); if (debug) tl_message("read max value = %d", max); if (min > max) { tl_warning ("min greater than max : min = %d, max = %d!!, in file %s", min, max, filename); tl_warning ("State No.%d State Value=%d", state_no, segment_seq[state_no].DiscreteValue() ); return -1; } if (debug) tl_message ("State No.%d , dim = %d : max = %d , min = %d", state_no, j, max, min ); segment_seq[state_no].SetMinMaxValue (j, min, max); // for j-th dimension //max[j][state_no] = max; //min[j][state_no] = min; // If mean value is not described, (min+max)/2 is automatically set (added on 1999 Oct 15th) ret = sscanf_int_with_seeking (&charp, &mean); if (debug) tl_message ("sscanf_int_with_seeking done"); if (ret==FALSE) { if (debug) tl_message ("mean not found (state_no = %d, j = %d)", state_no, j); segment_seq[state_no].SetMeanValue (j, (max + min)/2); if (debug) tl_message("there is no mean value, so set %d", (int)(max + min)/2); } else { if (debug) tl_message ("mean found"); segment_seq[state_no].SetMeanValue (j, mean); if (debug) tl_message("read and set mean value = %d", mean); } } } fclose (fp); if (debug) tl_message ("finished successfully"); return 1; }
/*---------------------------------------------------------------------------*/ int Connection::Receive (int type, gpointer data) { int ret, debug=0; char word[MAX_STRING]; // if (!connection) return CONNECTION_FAIL; if (type & CONNECTION_SELECT) { if (Select( )==CONNECTION_FAIL) return CONNECTION_FAIL; } if( type & CONNECTION_BYTE ) { // 通信できていない場合は Retry するようにする : 1999 Apr 26th int fd; fd = FdRead( ); do { ret = my_receive (fd, data, sizeof(char)); if (ret==-1) { tl_warning ("%s : STRING : Error(%d)!", GetName(), errno); return CONNECTION_FAIL; } } while( ret!=1 ); } else if( (type & CONNECTION_STRING) ) { // C で文字列を受けとる時は最後の '\n' を '\0' に変換する int fd, ret, p, debug=0; fd = FdRead( ); for (p=0;;p++) { do { ret = my_receive( fd, (gpointer)((char *)data+p), 1 ); if (ret==FALSE) tl_message ("%s : STRING : Error!", GetName()); if(debug) tl_message ("%c(%d)::", ((char *)data)[p], ((char *)data)[p]); } while( ret!=sizeof(char) ); if ( ((char *)data)[p]=='\n' ) break; if (ret!=sizeof(char) || p>=MAX_STRING) { tl_message ("%s : STRING : OverFlow Error!", name ); } } ((char *)data)[p] = '\0'; } else if( type & CONNECTION_WORD ) { FILE *fp; fp = FpRead(); if( fgets( word, MAX_STRING, fp )==NULL ) { tl_message ("WORD : Error!"); return CONNECTION_FAIL; } sscanf (word, "%s", (char *)data); } else if (type & CONNECTION_INTEGER) { int fd, value=0; fd = FdRead(); ret = my_receive( fd, &value, sizeof(int) ); if( ret!=sizeof(int) ) { tl_message ("INTEGER : Error!"); return CONNECTION_FAIL; } *( (int *)data ) = value; } else if (type & CONNECTION_DOUBLE) { int fd; double value=0.0; fd = FdRead (); ret = my_receive (fd, &value, sizeof(double)); if (ret!=sizeof(double)) { tl_warning ("<DOUBLE> : ret = %d ", ret); return FALSE; } *( (double *)data ) = value; } else if (type & CONNECTION_TLVECTOR) Receive_tlVector ((tlVector_t *)data); //KEEP AN EYE OVER HERE !!!! else if (type & CONNECTION_STREAM ) { // STREAM 型の場合,最初に int 型で長さを受けとってから,データをもらう int fd, length=0, p, tmp=5; fd = FdRead(); if(stream == NULL ) { tl_message ("STREAM :%s : Point is NULL!", GetName()); return CONNECTION_FAIL; } read_integer (fd, &tmp); tl_message ("Read Check 1 : length = %d", tmp); read_integer (fd, &length); tl_message ("Read Check 2 : length = %d", length); fsync(fd); if( tmp!=length ) { tl_message ("STREAM :%s : length mismatch %d!=%d", GetName(), tmp, length); ret = my_receive( fd, &tmp, sizeof(int) ); return CONNECTION_FAIL; } tl_message ("STREAM :%s : length = %d", GetName(), length ); *((int *)data) = length; if( length<=0 ) { tl_message ("STREAM :%s : length error!", GetName()); return CONNECTION_FAIL; } for (p=0; p<length; p++) { ret = my_receive( fd, (stream)+p, 1 ); if (ret!= 1) { tl_warning ("STREAM :%s : read error!", GetName()); return CONNECTION_FAIL; } } if(debug) tl_message ("STREAM :%s (2): length = %d", GetName(), length); } else { tl_message ("%s: Error! Set Send Type.(%d)", GetName(), type); return CONNECTION_FAIL; } return CONNECTION_SUCCESS; }
int Connection::Open (char *readfile, char *writefile, int target_port) { int type, debug=1; char filename[MAX_STRING]; if(debug) tl_message ("Start!"); type = GetType (); if(debug) tl_message ("Start<2>!"); // FIFO で,NORMAL の順番で Open if( (type & CONNECTION_FIFO) && (type & CONNECTION_FIFO_NORMAL) ) { if(debug) tl_message ("%s: FIFO Normal",GetName() ); strcpy( filename, readfile ); fd_read = open( filename, O_RDONLY ); fp_read = fdopen( fd_read, "r" ); strcpy( filename, writefile ); fd_write = open( filename, O_WRONLY ); fp_write = fdopen( fd_write, "w" ); if(fd_read ==FALSE || fp_read ==NULL || fd_write==FALSE ||fp_write==NULL ) { if(debug) tl_message ("non_reverse Error !!"); return CONNECTION_FAIL; } } // FIFO で,Reverse の順番で Open else if( (type & CONNECTION_FIFO) && (type & CONNECTION_FIFO_REVERSE) ) { if(debug) tl_message ("%s:FIFO Reverse", GetName()); strcpy( filename, writefile ); fd_write = open( filename, O_WRONLY ); fp_write = fdopen( fd_write, "w" ); strcpy( filename, readfile ); fd_read = open( filename, O_RDONLY ); fp_read = fdopen( fd_read, "r" ); if (fd_read ==FALSE || fp_read ==NULL || fd_write==FALSE || fp_write==NULL ) { if(debug) tl_message ("reverse Error !!"); return CONNECTION_FAIL; } } // Socket で,サーバー側の Open // Multi Access ではなく,1vs1の普通のサーバ else if ( (type & CONNECTION_SOCKET) && (type & CONNECTION_SERVER) ) { struct sockaddr_in me; int s_waiting, s; if(debug) tl_message ("%s:Socket Server %s:%d", GetName(), readfile, port ); port = target_port; bzero((char *)&me, sizeof(me)); me.sin_family = AF_INET; me.sin_port = htons(port); me.sin_addr.s_addr = INADDR_ANY; s_waiting = socket(AF_INET, SOCK_STREAM,0); bind (s_waiting, (const struct sockaddr *)&me,sizeof(me)); listen (s_waiting, 1); s = accept (s_waiting, NULL, NULL); close (s_waiting); fd_read = s; fd_write = s; fp_read = fdopen( fd_read, "r+" );// Read&Write fp_write = fp_read; if( fd_read==-1 || fp_read==NULL || fd_write==-1 || fp_write==NULL ) { if(debug) tl_message ("reverse Error !!"); return CONNECTION_FAIL; } } // マルチサーバーへのクライアント接続 else if( type & CONNECTION_MULTICLIENT ) // readfile にサーバホスト名が入っている MultiClientOpen (readfile, target_port); // Socket で,クライアント側の Open else if ( (type & CONNECTION_SOCKET) && (type & CONNECTION_CLIENT) ) { if(debug) tl_message ("%s:Socket Server %s:%d", GetName(), readfile, target_port); SocketClientOpen (readfile, target_port); } // Open の時のオプション,Type の指定エラー else { if(debug) tl_warning ("%s:Error !!", GetName() ); return CONNECTION_FAIL; } return CONNECTION_SUCCESS; }
// 変更 : 1999 Apr 24th // ・この関数を使うのは C プロセスなのでいつでも abc\n という列を出力する // 下手に相手が Lisp だから C だから,という小細工はしない方針 // 変更 : 2001 Sep 30th : DOUBLE 型への対応 // 変更 : 2002 Jan 30th : データを gpointer 型にする //----------------------------- // Input : *connection : 使用するコネクション構造体へのポインタ // Input : type : 文字列 or 1byte // Input : *data : 送信するデータ // 返値 : SUCCESS or FAIL // 注意 送信するデータが STRING 型の時は,'\n' を付けてはダメ!! // 注意 STREAM 型の時は,*data はデータの長さを意味する (Jan 15th) // 実際のデータバッファは SetStream で設定 int Connection::Send(int type, gpointer data) { int ret, debug=0; char string[MAX_STRING]; // tl_return_val_if_fail (connection, "Pointer connection is NULL", FALSE); // tl_return_val_if_fail (data, "Pointer of data is NULL", FALSE); if (type & CONNECTION_BYTE) { int fd; fd = FdWrite(); ret = my_send (fd, data, sizeof(char)); #if 0 if( ret!=sizeof(char) ) { tl_warning ("BYTE : Cannot write"); return CONNECTION_FAIL; } //#else // tl_return_val_if_fail ((ret==sizeof(char)), "BYTE : Connot write", FALSE); #endif } else if( (type & CONNECTION_STRING) ) { // C から文字列を送信する場合は最後の '\0' を '\n' に変換して送信する char tmp='\n'; int ret, fd, i; fd = FdWrite(); strcpy (string, (char *)data ); for (i=0; i<MAX_STRING; i++) { if( string[i]=='\0' ) { do { ret = my_send( fd, &tmp, 1 ); if( ret==-1 ) { tl_warning ("STRING : %s : %s", GetName(), string); } } while( ret!=1 ); break; } else { do { ret = my_send (fd, string+i, 1); if( ret==-1 ) tl_message ("STRING :%s : Error(%d)!", GetName (), errno ); } while (ret!=1); } } } else if (type & CONNECTION_WORD) { FILE *fp; fp = FpWrite(); fprintf (fp, "%s", (char *)data); fflush( fp ); } else if( type & CONNECTION_INTEGER ) Send_Integer (data); else if (type & CONNECTION_DOUBLE) { int fd; double value; fd = FdWrite (); value = *((double *)data); ret = my_send (fd, &value, sizeof(double)); fsync(fd); // tl_return_val_if_fail ((ret==sizeof(double)), "DOUBLE : Cannot write", FALSE); if (ret!=sizeof(double)) { tl_warning ("DOUBLE : Fd<%d> : Cannot write (%d)", fd, ret); return CONNECTION_FAIL; } } else if (type & CONNECTION_TLVECTOR) Send_tlVector ((tlVector_t *)data); else if( type & CONNECTION_STREAM ) { int fd, length, p; fd = FdWrite(); if( stream==NULL ) { tl_warning ("STREAM :%s :Point is NULL!", GetName() ); return CONNECTION_FAIL; } length = *(int *)data; if(debug) tl_message ("STREAM :%s : length = %d", GetName(), length); if( length <=0 ) { tl_warning ("STREAM :%s :length error !", GetName() ); return CONNECTION_FAIL; } // STREAM の時には,まずデータの長さを送信してから,実際のデータを送る if(debug) tl_message ("Check 1: length = %d", length ); ret = my_send( fd, &length, sizeof(int) ); fsync(fd); if( ret!=sizeof(int) ) tl_message ("write miss..." ); tl_message ("Check 2: length = %d", length ); ret = my_send( fd, &length, sizeof(int) ); fsync(fd); if( ret!=sizeof(int) ) tl_message ("write miss..." ); for( p=0; p<length; p++ ) { ret = my_send( fd, (stream)+p, 1 ); if( ret!=1 ) { tl_warning ("STREAM :%s : write error!", GetName()); return CONNECTION_FAIL; } } stream = NULL; } else { tl_message ("%s: Error! Set Send Type.(%d)", GetName(), type); return CONNECTION_FAIL; } return CONNECTION_SUCCESS; }