📄 commsdms.c
字号:
/*=====================================================================
Update list by Jason, 98.9.21
1. Add function NoDelayConnect
=======================================================================
=======================================================================
Update list by Jason, 97.12.27
1. Add judgement for No ETX
When etx="" is No ETX
Add a judgement in function SeekETX:
when ptr = tail, means reach the ETX
2. Remove parameter format in function CreateTcpStream,
when stx & etx use the default value, set format =1
else format = 0
=======================================================================
=====================================================================
Updated list by Jason, 97.11.15 :
1. MAX_TCP_STREAM_BUFFER = 30720
2. In function InitCAPI, remove the parameter: mps, set mps = MAX_TCP_STREAM_BUFFER
3. In function CreateTcpStream, add parameter: format
when format=1, use the default stx & etx, the parameter stx & etx in this function
should be omitted to "", and default stx & etx would be added to packet
automaticly when SendTcpPacket
when format=0, use the specified stx & etx string
4. Add function:
ChangeSTX(char *name, char *STX);
ChangeETX(char *name, char *ETX);
5. In function CAPINodeStatus, If no match name, suppress error log
========================================================================
====================================================================
Updated list by Jason, 97.08.19 :
1. Add stx & etx parameters in function CreateTcpStream,
and Change stx & etx from a char to a string
When use the default stx & etx, the stx & etx would be removed automaticly when receive
a packet and would be added when send a packet;
When use the specified stx & etx string, the stx & etx would not be removed or added
automaticly
2. Add function to compare stx & etx string:
int SeekSTX(struct TCP_Stream_Node_t *node, int ptr);
int SeekETX(struct TCP_Stream_Node_t *node, int ptr);
3. In function CreateTcpStream, add a var: RealIPMode
When input a real IP(hname) & port(sname), RealIPMode=1
=====================================================================*/
/*
COMM112.C
Communication model for 112 project
112
1996.9.10
*/
#ifdef CAPI_DOS
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <share.h>
#include <IO.H>
#ifdef _MSC_
#include <malloc.h>
#else
#include <alloc.h>
#endif
#include <string.h>
#include <memory.h>
#include <errno.h>
#include <sys\types.h>
#include <time.h>
/* pctcp development tool kit's header files */
#include <\tcp.dev\include\sys\types.h>
#include <sys\socket.h>
#include <4bsddefs.h>
#include <sys\time.h>
#include <netinet\in.h>
#include <netdb.h>
#include <arpa\inet.h>
#else /* UNIX */
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/file.h>
#include <sys/poll.h>
#include <stropts.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <signal.h>
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <errno.h>
#endif /* for UNIX */
#include "commsdms.h"
/* functions used internal */
struct TCP_Stream_Node_t *GetIdleTcpNode(void);
void tcp_timer(void);
void tcp_do_retry(void);
int accept_connect(struct TCP_Stream_Node_t *srv_node,char *new_node_name); //[x]
int GetPacket(char *packet,char *name); //[x]
int CAPIEnqueue(struct CAPI_Q_NODE_t *node); //[x]
int CAPIProcessStream(struct TCP_Stream_Node_t *node); //[x]
//Add by Jason, 98.9.21
int NoDelayConnect(int sk, struct sockaddr *des, int len);
/* === seek stx & etx, added by Jason, 97.8.19 === */
int SeekSTX(struct TCP_Stream_Node_t *node, int ptr);
int SeekETX(struct TCP_Stream_Node_t *node, int ptr);
/* =============================================== */
/* model's viriables */
//char comm_err_msg[512];
void(*record_err)(char *errmsg);
char tcp_errlog_file[40];
short int retry_time;
short unsigned tick_count = 0;
struct TCP_Stream_Node_t fst_node;
struct CAPI_Q_NODE_t *q_head,*q_tail;
int max_packet_size;
/**************************************************************************/
/*
Codes to Maintain CAPI Queue
*/
/*
Return:
0 -- failed
1 -- succeeded
*/
int CAPIEnqueue(struct CAPI_Q_NODE_t *node)
{
struct CAPI_Q_NODE_t *new_node;
/* 1. Allocate memory for new node */
new_node = (struct CAPI_Q_NODE_t*)calloc(1,sizeof(struct CAPI_Q_NODE_t));
if (new_node == NULL)
{
(*record_err)("CAPIEnqueue: Memory failed !");
return 0; /* failed */
}
/* 2. Allocate memory for new node's content */
new_node->content = (char *)calloc(node->length,sizeof(char));
if (new_node->content == NULL)
{
free(new_node);
(*record_err)("CAPIEnqueue: Memory for content failed !");
return 0; /* failed */
}
/* 3. copy info. to new node */
new_node->next = NULL;
new_node->length = node->length;
strcpy(new_node->stream_name,node->stream_name);
memcpy(new_node->content,node->content,node->length);
/* 4. update the queue pointer */
if (q_head == NULL)
{
q_head = new_node;
q_tail = new_node;
}
else
{
q_tail->next = new_node;
q_tail = new_node;
}
return 1;
}
/*
Return:
1 a packet was got
0 queue is empty
Note: 1. This function act as dequeue()
2. packet must point to a large enough area
3. packet is terminated by NULL
*/
int GetPacket(char *packet,char *name)
{
struct CAPI_Q_NODE_t *next_node;
if (q_head == NULL)
return 0;
else
{
strcpy(name,q_head->stream_name);
memcpy(packet,q_head->content,q_head->length);
packet[q_head->length] = 0;
next_node = q_head->next;
free(q_head->content); /* Free memory occupied by content */
free(q_head); /* Free memory occupied by the old NODE */
q_head = next_node;
if (q_head == NULL)
q_tail = NULL;
}
return 1;
}
/* This routine will not change anything in the queue
// Return:
// 1 a packet was got
// 0 message queue is empty
*/
int p_queue(char *packet,char *name)
{
if (q_head == NULL)
return 0;
else
{
strcpy(name,q_head->stream_name);
memcpy(packet,q_head->content,q_head->length);
}
return 1;
}
/**************************************************************************/
#ifdef CAPI_DOS
void record_log(char *msg)
{
char temp_buffer[512];
char datebuffer[18],timebuffer[18];
int fh;
_strdate(datebuffer);
_strtime(timebuffer);
sprintf(temp_buffer,"%s,%s CAPI:%s\n",datebuffer, timebuffer, msg );
fh = sopen(tcp_errlog_file,O_CREAT|O_RDWR|O_TEXT|O_APPEND,
SH_DENYNO ,S_IREAD|S_IWRITE);
if (fh != -1)
{
if (lseek(fh,0L,SEEK_END) >= 10L*1024L*1024L)/* max log file size is 10M */
{
close(fh);
unlink(tcp_errlog_file);
return;
}
write(fh, temp_buffer, strlen(temp_buffer));
close(fh);
}
}
#else /* UNIX */
void record_log(char *msg)
{
}
#endif
/* void InitCAPI(void(*record_e)(char *errmsg),char *errlogfile,int rt,int mps) */
/* Modified by Jason, 97.11.15 */
void InitCAPI(void(*record_e)(char *errmsg),char *errlogfile,int rt)
{
if (record_e == NULL)
record_err = record_log; /* the fault record log function */
else
record_err = record_e;
if (errlogfile == NULL)
#ifdef CAPI_DOS
strcpy(tcp_errlog_file,".\\tcperr.log"); /* default log file name */
#else
strcpy(tcp_errlog_file,"./tcperr.log");
#endif
else
strcpy(tcp_errlog_file,errlogfile);
if (rt == 0)
retry_time = 60; /* default is one minute */
else
retry_time = rt;
tick_count = 0;
/* max_packet_size = mps; */
max_packet_size = MAX_TCP_STREAM_BUFFER; /* Modified by Jason, 97.11.15 */
memset(&fst_node,0,sizeof(fst_node));
fst_node.type = TCP_NOTUSED;
fst_node.socket = -1;
q_head = NULL;
q_tail = NULL;
}
/* steps:
1. search for idle node in the current link, if find a idle node,
then return its pointer to caller, else go to step 2.
2. create a new node and add it to the current link. On success,
return the new node's pointer to caller, on failure return NULL
*/
struct TCP_Stream_Node_t *GetIdleTcpNode(void)
{
struct TCP_Stream_Node_t *current_node,*prev_node;
struct TCP_Stream_Node_t *new_node;
/* 1. check if the root node is idle */
if (fst_node.type == TCP_NOTUSED) return (&fst_node);
/* 2. look up the current for a idle node */
current_node = fst_node.next;
prev_node = &fst_node;
while (current_node != NULL) {
if (current_node->type == TCP_NOTUSED)
return current_node;
prev_node = current_node;
current_node = current_node->next;
}
/* 3. no idle node in the current link, try to create a new node */
new_node = (struct TCP_Stream_Node_t*)calloc(1,sizeof(struct TCP_Stream_Node_t));
if (new_node == NULL) {
(*record_err)("CAPI:GetIdleTcpNode: memory error !");
return (struct TCP_Stream_Node_t*)NULL;
}
/* add the new node into link */
memset(new_node,0,sizeof(struct TCP_Stream_Node_t));
prev_node->next = new_node;
new_node->next = NULL;
new_node->type = TCP_NOTUSED;
return new_node;
}
/*
on error return -1, else return the child socket.
Note: the default name for child node is the peer's IP address(dot form)
*/
int accept_connect(struct TCP_Stream_Node_t *srv_node,char *new_node_name)
{
int new_socket;
struct sockaddr_in peer;
int peersize;
char buffer[20];
char *cptr;
char temp_buffer[512];
peersize = sizeof(peer);
new_socket = accept(srv_node->socket,(struct sockaddr *)&peer,&peersize);
if (new_socket < 0) {
sprintf(temp_buffer,"failed to accept connection from %s",srv_node->name);
(*record_err)(temp_buffer);
return -1;
}
cptr = inet_ntoa(peer.sin_addr);
strcpy(buffer,cptr);
strcpy(new_node_name,buffer);
sprintf(buffer,"%d",ntohs(peer.sin_port));
strcat(new_node_name,buffer);
return new_socket;
}
/*
Returns:
-1 -- Failed
1 -- Succeeded
*/
/* stx & etx added by Jason, 97.8.19 */
/* Add format by Jason, 97.11.15
format = 1 : default stx & etx
format = 0 : not default stx & etx,
when SendTcpPacket, stx & etx would not be added to packet automaticly
*/
int CreateTcpStream(int type,char *name,char *hname,char *sname, char *stx, char *etx,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -