📄 zjmdmfuc.c
字号:
/*************************************************************************
* File name : zjmdmdrv.c
* Subsystem : modem卡驱动程序
* Target env : Linux
* Author : 谢红伟
* Last modified : 2002/04/30
* Description : This file contains public function and macro for access zj-modem driver
* Copyright : zjkj
* Note :
**************************************************************************/
#include <unistd.h>
#include <fcntl.h>
#include "pthread.h"
#include "../tdkio/pubdef.h"
#include "../tdkio/pubfunc.h"
#include "zjmdmfuc.h"
/************* Private macro define ********************/
#define only_DisconnCH(fd,chl_id) \
ioctl((fd),IOCTL_CMD_DISCONN | ((chl_id)<<4))
/******************************************************
* type:public
* 启动系统
*******************************************************/
void zj_SystemStart()
{
pthread_mutex_init (&mutex_comd, NULL);
}
/*******************************************************
* type:public
* 系统终止
*******************************************************/
void zj_SystemExit()
{
pthread_mutex_destroy (&mutex_comd);
}
/***********************************************
* 给modem卡发送数据
**********************************************/
inline ssize_t zj_write(int fd,char *Write_buf,unsigned long size,unsigned char chl_id,time_t timeout)
{
unsigned long len,sent_bytes = 0,ret;
time_t start_time = time(NULL);
if(fd<1) return -1;
if(fd<1 || chl_id>=CHL_NUM) return -1;
if(timeout<=0) timeout = DEF_SEND_TIMEOUT;
while(sent_bytes<size)
{
len = size-sent_bytes;
len = (len <<3) | (chl_id & 0x07);
ret = write(fd,Write_buf+sent_bytes,len);
if(ret>0)
sent_bytes += ret;
else if(ret==0)
sleep(1);
else
return sent_bytes;
if(time(NULL) - start_time > timeout)
return sent_bytes;
}
return sent_bytes;
}
/***********************************************
* 从卡上收数据
**********************************************/
inline ssize_t zj_read(int fd,char *Read_buf,unsigned long size,unsigned char chl_id)
{
unsigned long len;
if(fd<1 || chl_id>=CHL_NUM) return -1;
len = size;
len = (len <<3) | (chl_id & 0x07);
return read(fd,Read_buf,len);
}
/************************************************************
* 清空读缓冲
*************************************************************/
int zj_clean_read_buffer(int fd,unsigned char chl_id)
{
int try_count;
time_t start_time;
char tmp_buf[1024];
#ifdef _DEBUG
t_TdkMdmChl tdk;
Log(&tdk,"Cleaning read buffer...\n");
#endif
if(fd<0 || chl_id>=CHL_NUM) return;
if(fcntl (fd, F_SETFL,fcntl (fd, F_GETFL, 0) | O_NONBLOCK)<0)
return -1;
time(&start_time);
while(1)
{
if(zj_read(fd,tmp_buf,sizeof(tmp_buf),chl_id)<=0)
{
try_count++;
if(try_count>MAX_CLEAN_TIMES)
return 0;
usleep(10*1000);
}
else
{
try_count = 0;
}
usleep(1000);
if(time(NULL)-start_time>MAX_CLEAN_BUF_TIME)
{
#ifdef _DEBUG
Log(&tdk,"Fail:cleaning read buffer!\n");
#endif
return -1;
}
}
return 0;
}
/******************************************************
*得到通道的挂机状态
******************************************************/
int zj_GetHangupState(int fd,unsigned char chl_id)
{
int i,state_date;
zj_QueryState(fd,chl_id);
for(i=0; i<MAX_QUERY_TIME; i++)
{
usleep(1000);
state_date = zj_GetQueryResult(fd,chl_id);
if((unsigned char)state_date == CMD_HANGUP_BACK ||
(unsigned char)state_date == CMD_BRINGUP_BACK)
{
return state_date;
}
}
return -1;
}
/******************************************************
*确保通道工作正常
******************************************************/
int ValidateChannel(int fd,unsigned char chl_id)
{
int state_date;
pthread_mutex_lock(&mutex_comd);
state_date = zj_GetHangupState(fd,chl_id);
if((unsigned char)state_date == CMD_HANGUP_BACK ||
(unsigned char)state_date == CMD_BRINGUP_BACK)
{
pthread_mutex_unlock(&mutex_comd);
return 0;
}
//查状态失败,开通道
zj_OpenCH(fd,chl_id);
usleep(10*1000);
state_date = zj_GetHangupState(fd,chl_id);
if((unsigned char)state_date == CMD_HANGUP_BACK ||
(unsigned char)state_date == CMD_BRINGUP_BACK)
{
pthread_mutex_unlock(&mutex_comd);
return 1;
}
//开通道后查状态仍然失败,恢复错误的序列
zj_RecoverHead(fd,chl_id);
state_date = zj_GetHangupState(fd,chl_id);
if((unsigned char)state_date == CMD_HANGUP_BACK ||
(unsigned char)state_date == CMD_BRINGUP_BACK)
{
pthread_mutex_unlock(&mutex_comd);
return 2;
}
//仍然失败,再开通道
zj_OpenCH(fd,chl_id);
usleep(10*1000);
state_date = zj_GetHangupState(fd,chl_id);
if((unsigned char)state_date == CMD_HANGUP_BACK ||
(unsigned char)state_date == CMD_BRINGUP_BACK)
{
pthread_mutex_unlock(&mutex_comd);
return 3;
}
pthread_mutex_unlock(&mutex_comd);
return -1;
}
/******************************************************
*挂断modem指定的通道的连接
******************************************************/
int zj_DisconnCH(int fd,unsigned char chl_id)
{
int i;
for(i=0;i<MAX_QUERY_TIME;i++) //wait for command send over
{
if(zj_CmdSendOver(fd,chl_id))
break;
usleep(1000);
}
if(i>=MAX_QUERY_TIME)
{
return -1;
}
only_DisconnCH(fd,chl_id);
switch(ValidateChannel(fd,chl_id))
{
case 0: //正常
return 0;
break;
case 1: //开通道后正常
case 2: //恢复错误序列后正常
case 3: //再开通道后正常
return only_DisconnCH(fd,chl_id);
break;
default: //错误
return -1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -