|
|
#include <jni.h>
|
|
|
#include <string>
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
#include <unistd.h>
|
|
|
#include <sys/ioctl.h>
|
|
|
#include <linux/spi/spidev.h>
|
|
|
#include <android/log.h>
|
|
|
#include <stdio.h>
|
|
|
#include <dirent.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <unistd.h>
|
|
|
#include <fcntl.h>
|
|
|
#include <string.h>
|
|
|
#include <termios.h>
|
|
|
#include <time.h>
|
|
|
#include "GPIOControl.h"
|
|
|
#include "WeatherComm.h"
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
SIO_PARAM_SERIAL_DEF serialport;
|
|
|
float weatherpntmsg[10];
|
|
|
|
|
|
static void set_baudrate (struct termios *opt, unsigned int baudrate)
|
|
|
{
|
|
|
cfsetispeed(opt, baudrate);
|
|
|
cfsetospeed(opt, baudrate);
|
|
|
}
|
|
|
|
|
|
static void set_data_bit (struct termios *opt, unsigned int databit)
|
|
|
{
|
|
|
opt->c_cflag &= ~CSIZE;
|
|
|
switch (databit)
|
|
|
{
|
|
|
case 8:
|
|
|
opt->c_cflag |= CS8;
|
|
|
break;
|
|
|
case 7:
|
|
|
opt->c_cflag |= CS7;
|
|
|
break;
|
|
|
case 6:
|
|
|
opt->c_cflag |= CS6;
|
|
|
break;
|
|
|
case 5:
|
|
|
opt->c_cflag |= CS5;
|
|
|
break;
|
|
|
default:
|
|
|
opt->c_cflag |= CS8;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void set_parity (struct termios *opt, char parity)
|
|
|
{
|
|
|
switch (parity)
|
|
|
{
|
|
|
case'N':/* 无校验 */
|
|
|
case 'n':
|
|
|
opt->c_cflag &= ~PARENB;
|
|
|
break;
|
|
|
case'E':/*偶校验*/
|
|
|
case 'e':
|
|
|
opt->c_cflag |= PARENB;
|
|
|
opt->c_cflag &= ~PARODD;
|
|
|
break;
|
|
|
case'O':/* 奇校验 */
|
|
|
case 'o':
|
|
|
opt->c_cflag |= PARENB;
|
|
|
opt->c_cflag |= ~PARODD;
|
|
|
break;
|
|
|
default: /*其它选择为无校验 */
|
|
|
opt->c_cflag &= ~PARENB;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void set_stopbit (struct termios *opt, const char *stopbit)
|
|
|
{
|
|
|
if (strcmp(stopbit, "1") == 0)
|
|
|
{
|
|
|
opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */
|
|
|
}
|
|
|
else if(0 == strcmp(stopbit, "1.5"))
|
|
|
{
|
|
|
opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */
|
|
|
}
|
|
|
else if(0 == strcmp (stopbit,"2"))
|
|
|
{
|
|
|
opt->c_cflag |= CSTOPB; /*2 位停止位 */
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
opt->c_cflag &= ~CSTOPB; /*1 位停止位 */
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin )
|
|
|
{
|
|
|
struct termios opt;
|
|
|
tcgetattr(fd, &opt);
|
|
|
set_baudrate(&opt, baudrate);
|
|
|
//opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */
|
|
|
opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG);
|
|
|
set_data_bit(&opt, databit);
|
|
|
set_parity(&opt, parity);
|
|
|
set_stopbit(&opt, stopbit);
|
|
|
opt.c_oflag = 0;
|
|
|
//opt.c_lflag |= 0;
|
|
|
opt.c_oflag &= ~OPOST;
|
|
|
opt.c_cc[VTIME] = vtime;
|
|
|
opt.c_cc[VMIN] = vmin;
|
|
|
tcflush (fd, TCIFLUSH);
|
|
|
return (tcsetattr (fd, TCSANOW, &opt));
|
|
|
}
|
|
|
|
|
|
static void setInt(int cmd, int value)
|
|
|
{
|
|
|
int fd = open("/dev/mtkgpioctrl", O_RDONLY);
|
|
|
IOT_PARAM param;
|
|
|
param.cmd = cmd;
|
|
|
param.value = value;
|
|
|
// LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
|
|
|
if( fd > 0 )
|
|
|
{
|
|
|
int res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
|
|
|
// LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
|
|
|
close(fd);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
static void setRS485Enable(bool z) {
|
|
|
setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
|
|
|
}
|
|
|
|
|
|
static void set485WriteMode() {
|
|
|
setInt(CMD_SET_485_STATE, 1);
|
|
|
}
|
|
|
|
|
|
static void set485ReadMode() {
|
|
|
setInt(CMD_SET_485_STATE, 0);
|
|
|
}
|
|
|
static void set12VEnable(bool z) {
|
|
|
setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
|
|
|
}
|
|
|
|
|
|
static void setCam3V3Enable(bool enabled)
|
|
|
{
|
|
|
setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
|
|
|
}
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
* 气象数据处理 *
|
|
|
**********************************************************************************/
|
|
|
void PortDataProcess( void )
|
|
|
{
|
|
|
float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
|
|
|
//WORD uDevAddr;
|
|
|
unsigned char cmdidx;
|
|
|
int i, j, aipnt, datanum;
|
|
|
SIO_PARAM_SERIAL_DEF *pPortParam;
|
|
|
char szbuf[64];
|
|
|
|
|
|
pPortParam = &serialport;
|
|
|
//取出装置地址,开始处理地址+++
|
|
|
if(0x02 == pPortParam->m_au8RecvBuf[5])
|
|
|
{
|
|
|
//pPortParam->devaddr = pPortParam->m_au8RecvBuf[4];
|
|
|
return;
|
|
|
}
|
|
|
cmdidx = pPortParam->m_au8RecvBuf[5];
|
|
|
#if 0
|
|
|
aipnt = pPortParam->SameTypeDevIdx;
|
|
|
uDevAddr = serialport->m_au8RecvBuf[4];
|
|
|
if(0 == srdt.IsReadWireTem)
|
|
|
{
|
|
|
if(uDevAddr != pPortParam->devaddr)
|
|
|
return;
|
|
|
}
|
|
|
#endif
|
|
|
fvalua = &fvalue;
|
|
|
datanum = pPortParam->m_au8RecvBuf[6];
|
|
|
if((0x08 != cmdidx) && (0x09 != cmdidx))
|
|
|
return;
|
|
|
|
|
|
for(i = 0, j=7; (i<datanum) && (j<6+pPortParam->m_au8RecvBuf[1]); i++, j+=5 )
|
|
|
{
|
|
|
if(0x08 == cmdidx)
|
|
|
fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16)
|
|
|
+(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4];
|
|
|
else
|
|
|
{
|
|
|
*(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4];
|
|
|
*((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3];
|
|
|
*((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2];
|
|
|
*((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1];
|
|
|
}
|
|
|
switch(pPortParam->m_au8RecvBuf[j])
|
|
|
{
|
|
|
case 1: /*温度*/
|
|
|
weatherpntmsg[0] = fvalue;
|
|
|
LOGE("温度:%0.3f ", fvalue);
|
|
|
break;
|
|
|
case 2: /*气压*/
|
|
|
weatherpntmsg[5] = fvalue;
|
|
|
LOGE("气压:%0.3f ", fvalue);
|
|
|
break;
|
|
|
case 3: /*湿度*/
|
|
|
weatherpntmsg[1] = fvalue;
|
|
|
LOGE("湿度:%0.3f ", fvalue);
|
|
|
break;
|
|
|
case 4: /*雨量*/
|
|
|
break;
|
|
|
case 5: /*日照*/
|
|
|
break;
|
|
|
case 6: /*风速*/
|
|
|
weatherpntmsg[2] = fvalue;
|
|
|
LOGE("风速:%0.3f ", fvalue);
|
|
|
break;
|
|
|
case 7: /*风向*/
|
|
|
weatherpntmsg[3] = fvalue;
|
|
|
LOGE("风向:%0.3f ", fvalue);
|
|
|
break;
|
|
|
case 8: /*拉力*/
|
|
|
case 9: /*倾角传感器X轴倾角*/
|
|
|
case 10: /*倾角传感器Y轴倾角*/
|
|
|
case 11: /*测温球导线温度*/
|
|
|
case 12: /*测温球内部温度*/
|
|
|
break;
|
|
|
case 13: /*测温球导线X轴倾角*/
|
|
|
break;
|
|
|
case 14: /*测温球导线Y轴倾角*/
|
|
|
break;
|
|
|
case 15: /*测温球导线电流*/
|
|
|
break;
|
|
|
case 16: /*测温球电池电压*/
|
|
|
break;
|
|
|
case 17: /*A相泄漏电流平均值;*/
|
|
|
break;
|
|
|
case 18: /*A相泄漏电流最大值;*/
|
|
|
break;
|
|
|
case 19: /*A相超过3mA的脉冲频次*/
|
|
|
break;
|
|
|
case 20: /*A相超过10mA的脉冲频次*/
|
|
|
break;
|
|
|
case 21: /*B相泄漏电流平均值;*/
|
|
|
break;
|
|
|
case 22: /*B相泄漏电流最大值;*/
|
|
|
break;
|
|
|
case 23: /*B相超过3mA的脉冲频次*/
|
|
|
break;
|
|
|
case 24: /*B相超过10mA的脉冲频次*/
|
|
|
case 25: /*C相泄漏电流平均值;*/
|
|
|
case 26: /*C相泄漏电流最大值;*/
|
|
|
case 27: /*C相超过3mA的脉冲频次*/
|
|
|
case 28: /*C相超过10mA的脉冲频次*/
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//***************************************************************
|
|
|
//* 按照协议格式化接收数据 *
|
|
|
//***************************************************************
|
|
|
static void RecvData(u_char *buf, int len)// 规约读数据处理
|
|
|
{
|
|
|
int i, ictime;
|
|
|
//WORD crc, check;
|
|
|
SIO_PARAM_SERIAL_DEF *pPortParam;
|
|
|
|
|
|
pPortParam = &serialport;
|
|
|
ictime = (int)time(NULL);
|
|
|
|
|
|
if(pPortParam->m_iRecvLen == 0)
|
|
|
{
|
|
|
pPortParam->iRecvTime = ictime;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0))
|
|
|
pPortParam->iRecvTime = ictime;
|
|
|
else if(ictime - pPortParam->iRecvTime > 2)
|
|
|
{
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
pPortParam->m_iRevStatus = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
for(i=0; i<len; i++)
|
|
|
{
|
|
|
switch(pPortParam->m_iRevStatus)
|
|
|
{
|
|
|
case 0: // 0x68
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
if(0x68 == buf[i])
|
|
|
pPortParam->m_iRevStatus++;
|
|
|
else
|
|
|
pPortParam->m_iRevStatus = 18;
|
|
|
break;
|
|
|
case 1: // len1
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
pPortParam->m_iRevStatus++;
|
|
|
break;
|
|
|
case 2: // len2
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2])
|
|
|
{
|
|
|
pPortParam->m_iRevStatus++;
|
|
|
pPortParam->m_iNeedRevLength = buf[i]+5;
|
|
|
}
|
|
|
else
|
|
|
pPortParam->m_iRevStatus = 18;
|
|
|
break;
|
|
|
case 3: // 0x68
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
pPortParam->m_iNeedRevLength--;
|
|
|
if(0x68 == buf[i])
|
|
|
pPortParam->m_iRevStatus++;
|
|
|
else
|
|
|
pPortParam->m_iRevStatus = 18;
|
|
|
break;
|
|
|
case 4: // 正确接收数据
|
|
|
pPortParam->m_iNeedRevLength--;
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
if(pPortParam->m_iNeedRevLength > 0)
|
|
|
break;
|
|
|
if(buf[i] != 0x16)
|
|
|
{
|
|
|
pPortParam->m_iRevStatus=18;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
//if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE)
|
|
|
{
|
|
|
PortDataProcess();
|
|
|
pPortParam->m_iRevStatus = 0;
|
|
|
pPortParam->RevCmdFlag = 1;
|
|
|
}
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
break;
|
|
|
case 255:// 错误接收数据
|
|
|
default:
|
|
|
if(buf[i] == 0x68)
|
|
|
{
|
|
|
pPortParam->m_iRevStatus = 1;
|
|
|
pPortParam->m_iRecvLen = 1;
|
|
|
pPortParam->m_au8RecvBuf[0] = buf[i];
|
|
|
}
|
|
|
else if(buf[i] == 0x16)
|
|
|
{
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
pPortParam->m_iRevStatus = 0;
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
if(pPortParam->m_iRecvLen > 200)
|
|
|
{
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static long get_msec(void )
|
|
|
{
|
|
|
struct timeval tv;
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
long time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000;
|
|
|
|
|
|
return time_in_msec;
|
|
|
}
|
|
|
//int inum =0;
|
|
|
//int itimecnt=0;
|
|
|
static int weather_comm(SERIAL_PARAM weatherport)
|
|
|
{
|
|
|
int fd = -1;
|
|
|
int len, i,ret, icnt=0;
|
|
|
long ictime, iruntime, isendtime, irecvtime;
|
|
|
unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16};
|
|
|
char recvbuf[256], szbuf[512];
|
|
|
//char serial_description[] = "/dev/ttyS0";
|
|
|
|
|
|
#if 0
|
|
|
DIR *dir = opendir("/dev");
|
|
|
if (dir == NULL) {
|
|
|
LOGE("_test_ opendir");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
// 读取目录项
|
|
|
struct dirent *entry;
|
|
|
while ((entry = readdir(dir)) != NULL) {
|
|
|
// 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头
|
|
|
if ((strncmp(entry->d_name, "ttyS2", 5) == 0) ||
|
|
|
(strncmp(entry->d_name, "ttyS0", 5) == 0)) {
|
|
|
LOGE("_test_ Found serial port: %s\n", entry->d_name);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 关闭目录
|
|
|
closedir(dir);
|
|
|
#endif
|
|
|
serialport.RevCmdFlag = 1;
|
|
|
serialport.m_iRecvLen = 0;
|
|
|
serialport.m_iRevStatus = 0;
|
|
|
|
|
|
set12VEnable(true);
|
|
|
setCam3V3Enable(true);
|
|
|
setRS485Enable(true);
|
|
|
sleep(2);
|
|
|
//ictime = (int)time(NULL);
|
|
|
ictime = get_msec();
|
|
|
for(;;)
|
|
|
{
|
|
|
if(fd < 0)
|
|
|
{
|
|
|
fd = open(weatherport.pathname, O_RDWR | O_NDELAY);
|
|
|
//fd = open(weatherport.pathname, O_RDWR | O_NOCTTY);
|
|
|
if(fd < 0)
|
|
|
{
|
|
|
LOGE("_test_ open serial error \n");
|
|
|
perror(weatherport.pathname);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */
|
|
|
if(ret < 0)
|
|
|
{
|
|
|
LOGE("_test_ set uart arrt faile \n");
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
usleep(10000);
|
|
|
//iruntime = (int)time(NULL);
|
|
|
iruntime = get_msec();
|
|
|
if((iruntime - ictime > 120000) || (iruntime - ictime < 0))
|
|
|
ictime = iruntime;
|
|
|
if(iruntime - ictime > 20000)
|
|
|
{
|
|
|
memset(szbuf, 0, sizeof(szbuf));
|
|
|
sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0);
|
|
|
LOGE("%s", szbuf);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if(1 == serialport.RevCmdFlag)
|
|
|
{
|
|
|
set485WriteMode();
|
|
|
|
|
|
len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */
|
|
|
serialport.RevCmdFlag = 0;
|
|
|
LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime);
|
|
|
//isendtime = time(NULL);
|
|
|
isendtime = get_msec();
|
|
|
if (len < 0) {
|
|
|
LOGE("write data error \n");
|
|
|
return -1;
|
|
|
} else {
|
|
|
memset(szbuf, 0, sizeof(szbuf));
|
|
|
sprintf(szbuf, "Send:");
|
|
|
for (i = 0; i < len; i++) {
|
|
|
sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]);
|
|
|
}
|
|
|
LOGE("%s", szbuf);
|
|
|
//icnt = 0;
|
|
|
//inum++;
|
|
|
}
|
|
|
tcdrain(fd);
|
|
|
//usleep(50000);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//irecvtime = time(NULL);
|
|
|
irecvtime = get_msec();
|
|
|
if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0))
|
|
|
isendtime = irecvtime;
|
|
|
if (irecvtime-isendtime > 300)
|
|
|
{
|
|
|
LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime);
|
|
|
serialport.RevCmdFlag = 1;
|
|
|
serialport.m_iRecvLen = 0;
|
|
|
serialport.m_iRevStatus = 0;
|
|
|
close(fd);
|
|
|
//set12VEnable(false);
|
|
|
//setCam3V3Enable(false);
|
|
|
//setRS485Enable(false);
|
|
|
fd = -1;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
set485ReadMode();
|
|
|
memset(recvbuf, 0, sizeof(recvbuf));
|
|
|
len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */
|
|
|
if (len < 0) {
|
|
|
LOGE("serial read error \n");
|
|
|
continue;
|
|
|
}
|
|
|
if(0 == len)
|
|
|
{
|
|
|
//icnt++;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
memset(szbuf, 0, sizeof(szbuf));
|
|
|
sprintf(szbuf, "Recv:");
|
|
|
for (i = 0; i < len; i++) {
|
|
|
sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]);
|
|
|
}
|
|
|
__android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf);
|
|
|
RecvData((u_char*)recvbuf, len);
|
|
|
//LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt);
|
|
|
icnt = 0;
|
|
|
//serialport.RevCmdFlag =1;
|
|
|
}
|
|
|
|
|
|
close(fd);
|
|
|
set12VEnable(false);
|
|
|
setCam3V3Enable(false);
|
|
|
setRS485Enable(false);
|
|
|
|
|
|
//exit(-1);
|
|
|
return(0);
|
|
|
}
|
|
|
|
|
|
int serial_port_comm()
|
|
|
{
|
|
|
SERIAL_PARAM portparm;
|
|
|
|
|
|
//struct timeval tv;
|
|
|
|
|
|
//gettimeofday(&tv, NULL);
|
|
|
//long time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec;
|
|
|
|
|
|
//LOGE("Current time in microseconds: %ld\n", time_in_microseconds);
|
|
|
|
|
|
#if 1
|
|
|
memset(portparm.pathname, 0, sizeof(portparm.pathname));
|
|
|
sprintf(portparm.pathname, "/dev/ttyS0");
|
|
|
portparm.parity = 'N';
|
|
|
portparm.databit = 8;
|
|
|
portparm.baudrate = B9600;
|
|
|
memset(portparm.stopbit, 0, sizeof(portparm.stopbit));
|
|
|
sprintf(portparm.stopbit, "1");
|
|
|
#endif
|
|
|
//itimecnt = (int)time(NULL);
|
|
|
|
|
|
//for(;;)
|
|
|
weather_comm(portparm);
|
|
|
return 0;
|
|
|
}
|
|
|
|