Ejemplo n.º 1
0
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
sys_res gd5100_Transmit(p_gd5100 p, p_gd5100 pD)
{
	sys_res res;
	t_gd5100_header xH;
	uint_t nCS;
	buf b = {0};

	buf_Push(b, p->rmsg->data->p, p->rmsg->data->len);
	xH.sc1 = 0x68;
	xH.rtua = p->rmsg->rtua;
	xH.terid = p->rmsg->terid;
	xH.msta = p->rmsg->msta;
	xH.fseq = p->rmsg->fseq;
	xH.iseq = p->rmsg->iseq;
	xH.sc2 = 0x68;
	xH.code = p->rmsg->code;
	xH.abn = p->rmsg->abn;
	xH.dir = p->rmsg->dir;
	xH.len = b->len;
	nCS = cs8(&xH, sizeof(t_gd5100_header));
	nCS += cs8(b->p, b->len);
	buf_PushData(b, 0x1600 | (nCS & 0xFF), 2);
	res = dlrcp_TmsgSend(&pD->parent, &xH, sizeof(t_gd5100_header), b->p, b->len, DLRCP_TMSG_RESPOND);
	buf_Release(b);
	return res;
}
Ejemplo n.º 2
0
//-------------------------------------------------------------------------
//发送报文
//-------------------------------------------------------------------------
sys_res gwvms_TmsgSend(p_gwvms p, uint_t nFType,uint_t nPType, buf b, uint_t nType)
{
	t_gwvms_header xH;
	uint16_t nCRC;
	buf bBuf = {0};

	gwvms_TmsgHeaderInit(p, &xH);
	if (nType == DLRCP_TMSG_REPORT) {
		if (p->parent.pfc == 0)
			p->parent.pfc = 1;
		else
			p->parent.pfc += 1;
		xH.fseq = p->parent.pfc;
	} else
		xH.fseq = p->fseq;
	xH.ftype = nFType;
	xH.ptype = nPType;
	xH.len = b->len;
	buf_Push(bBuf,&xH,sizeof(t_gwvms_header));
	buf_Push(bBuf,b->p,b->len);
 	nCRC = crc16(bBuf->p+2, bBuf->len-2);
	buf_Release(bBuf);
	buf_PushData(b, nCRC, 2);
	buf_PushData(b, 0x96, 1);
	return dlrcp_TmsgSend(&p->parent, &xH, sizeof(t_gwvms_header), b->p, b->len, nType);
}
Ejemplo n.º 3
0
//-------------------------------------------------------------------------
//登录、心跳
//-------------------------------------------------------------------------
 static sys_res gwvms_TmsgLinkcheck (void *p, uint_t nCmd)
 {
 	sys_res res;
 	buf b = {0};

 	res = gwvms_TmsgSend(p, 0x01,0x01, b, DLRCP_TMSG_REPORT);//心跳
 	buf_Release(b);
 	return res;
 }
Ejemplo n.º 4
0
sys_res dlt645_Meter(chl c, buf b, uint_t nTmo)
{
	uint8_t *pH, aAdr[6];
#if DLT645_DIR_CTRL
	p_dev_uart pUart;
#endif

#if DLT645_DIR_CTRL
	gpio_Set(2, 0);
	//稳定总线
	chl_Send(c, dlt645_aFE, 4);
	chl_Send(c, b->p, b->len);
	pUart = (p_dev_uart)(c->pIf);
	if (pUart->para.baud < 2400)
		sys_Delay(200000);
	else
		sys_Delay(100000);
	gpio_Set(2, 1);
#else
	chl_Send(c, dlt645_aFE, 4);
	chl_Send(c, b->p, b->len);
#endif

	dlt645_DbgOut(1, b->p, b->len);

	memcpy(aAdr, &b->p[1], 6);
	buf_Release(b);
	for (nTmo /= OS_TICK_MS; nTmo; nTmo--) {
		if (chl_RecData(c, b, OS_TICK_MS) != SYS_R_OK)
			continue;
		pH = dlt645_PacketAnalyze(b->p, b->len);
		if (pH == NULL)
			continue;
		buf_Remove(b, pH - b->p);

		dlt645_DbgOut(0, b->p, b->p[9] + (DLT645_HEADER_SIZE + 2));

		if (memcmp(&b->p[1], aAdr, 6)) {
			buf_Remove(b, DLT645_HEADER_SIZE);
			continue;
		}
		buf_Remove(b, DLT645_HEADER_SIZE - 2);
		if (b->p[0] & BITMASK(7)) {
			byteadd(&b->p[2], -0x33, b->p[1]);
			return SYS_R_OK;
		}
	}
	return SYS_R_TMO;
}
Ejemplo n.º 5
0
static int vk321x_RegRead(uint_t nChl, uint_t nReg)
{
	uint_t i;
	int res = -1;
	buf b = {0};

	nReg |= (nChl << 4);
	for (i = VK321X_TIMEOUT / 200; i; i--) {
		if (uart_Send(vk321x_port, &nReg, 1) == SYS_R_OK) {
			if (uart_RecData(vk321x_port, b, 200) == SYS_R_OK) {
				res = b->p[0];
				buf_Release(b);
				break;
			}
		}
	}
	return res;
}
Ejemplo n.º 6
0
//-------------------------------------------------------------------------
//分析报文
//-------------------------------------------------------------------------
static sys_res gwvms_RmsgAnalyze(void *args)
{
	p_gwvms p = (t_gwvms *)args;
	uint8_t *pTemp;
	uint16_t nCRC;
	p_gwvms_header pH;
	p_dlrcp pRcp = &p->parent;

	chl_RecData(pRcp->chl, pRcp->rbuf, OS_TICK_MS);
	for (; ; buf_Remove(pRcp->rbuf, 1)) {
		for (; ; buf_Remove(pRcp->rbuf, 1)) {
			//不足报文头长度
			if (pRcp->rbuf->len < sizeof(t_gwvms_header))
				return SYS_R_ERR;
			pH = (p_gwvms_header)pRcp->rbuf->p;
			if (pH->sc == 0x5AA5){
				if (pH->len > GWVMS_DATA_SIZE)
					continue;
				break;
			}
		}
		//不足长度
		if (pRcp->rbuf->len < (sizeof(t_gwvms_header) + pH->len + 2))
			return SYS_R_ERR;
		pTemp = pRcp->rbuf->p + sizeof(t_gwvms_header) + pH->len;
		nCRC = *pTemp<<8 | *(pTemp+1);
		pTemp += 2;
		//CRC
		if (crc16(pRcp->rbuf->p + 2, sizeof(t_gwvms_header) + pH->len - 2) != nCRC)
			continue;
		//结束符
		if (*pTemp != 0x96)
			continue;
		//接收到报文
		p->fseq = pH->fseq;
		p->ftype = pH->ftype;
		p->ptype = pH->ptype;
		
		buf_Release(p->data);
		buf_Push(p->data, pRcp->rbuf->p + sizeof(t_gwvms_header), pH->len);
		buf_Remove(pRcp->rbuf, sizeof(t_gwvms_header) + pH->len + 2);
		return SYS_R_OK;
	}
}
Ejemplo n.º 7
0
// 中继转发645帧20130906
// b - 输入发送645帧与输出接收的645帧
sys_res dlt645_Transmit(chl c, buf b, uint_t nTmo)
{
	uint8_t *pH;

	chl_Send(c, dlt645_aFE, 4);
	chl_Send(c, b->p, b->len);

	dlt645_DbgOut(1, b->p, b->len);

	buf_Release(b);
	for (nTmo /= OS_TICK_MS; nTmo; nTmo--) {
		if (chl_RecData(c, b, OS_TICK_MS) != SYS_R_OK)
			continue;
		pH = dlt645_PacketAnalyze(b->p, b->len);
		if (pH == NULL)
			continue;
		buf_Remove(b, pH - b->p);
		return SYS_R_OK;
	}
	return SYS_R_ERR;
}
Ejemplo n.º 8
0
//-------------------------------------------------------------------------
//登录
//-------------------------------------------------------------------------
static sys_res gd5100_TmsgLinkcheck (void *p, uint_t nCmd)
{
	sys_res res;
	buf b = {0};

	switch (nCmd) {
	case DLRCP_LINKCHECK_LOGIN:
		nCmd = GD5100_CCODE_LOGIN;
		buf_Push(b, ((p_gd5100)p)->pwd, 3);
		break;
	case DLRCP_LINKCHECK_LOGOUT:
		nCmd = GD5100_CCODE_LOGOUT;
		break;
	default:
		nCmd = GD5100_CCODE_KEEPALIVE;
		break;
	}
	res = gd5100_TmsgSend(p, nCmd, b, DLRCP_TMSG_REPORT);
	buf_Release(b);
	return res;
}
Ejemplo n.º 9
0
static void _vk321x_ItHandler()
{
	p_dev_uart pUart;
	p_uart_def pDef;
	int res;
	uint_t i, nLen, nGIR, nReg;
	buf b = {0};

	if ((res = vk321x_RegRead(0, VK321X_GIR)) == -1)
		return;
	nGIR = res;
	for (pDef = tbl_bspUartDef, i = 0; pDef < ARR_ENDADR(tbl_bspUartDef); pDef++, i++) {
		if (pDef->type != UART_T_VK321X)
			continue;
		pUart = uart_Dev(i);
		if (nGIR & BITMASK(pDef->id)) {
			while (1) {
				//Rx Fifo Not Empty
				if ((res = vk321x_RegRead(pDef->id, VK321X_SSR)) == -1)
					return;
				if (res & BITMASK(0))
					break;
				//Get rx fifo num
				if ((res = vk321x_RegRead(pDef->id, VK321X_SFSR)) == -1)
					return;
				nLen = (res - 1) & 0x0F;
				nReg = 0x40 | (pDef->id << 4) | nLen;
				if (uart_Send(vk321x_port, &nReg, 1) == SYS_R_OK)
					if (uart_RecLength(vk321x_port, b, nLen + 1, VK321X_TIMEOUT) == SYS_R_OK) {
#if IO_BUF_TYPE == BUF_T_BUFFER
						buf_Push(pUart->bufrx, b->p, nLen + 1);
#else
						dque_Push(dqueue, pUart->parent->id | UART_DQUE_RX_CHL, b->p, nLen + 1);
#endif
						buf_Release(b);
					}
			}
		}
	}
}
Ejemplo n.º 10
0
afs_int32 cm_RequestWillBlock(cm_bkgRequest_t *rp)
{
    afs_int32 willBlock = 0;

    if (rp->procp == cm_BkgStore) {
        /*
         * If the datastoring flag is set, it means that another
         * thread is already performing an exclusive store operation
         * on this file.  The exclusive state will be cleared once
         * the file server locks the vnode.  Therefore, at most two
         * threads can be actively involved in storing data at a time
         * on a file.
         */
        lock_ObtainRead(&rp->scp->rw);
        willBlock = (rp->scp->flags & CM_SCACHEFLAG_DATASTORING);
        lock_ReleaseRead(&rp->scp->rw);
    }
    else if (rp->procp == RDR_BkgFetch || rp->procp == cm_BkgPrefetch) {
        /*
         * Attempt to determine if there is a conflict on the requested
         * range of the file.  If the first in the range does not exist
         * in the cache assume there is no conflict.  If the buffer does
         * exist, check to see if an I/O operation is in progress
         * by using the writing and reading flags as an indicator.
         */
        osi_hyper_t base;
        cm_buf_t *bufp = NULL;

        base.LowPart = rp->p1;
        base.HighPart = rp->p2;

        bufp = buf_Find(&rp->scp->fid, &base);
        if (bufp) {
            willBlock = (bufp->flags & (CM_BUF_WRITING|CM_BUF_READING));
            buf_Release(bufp);
        }
    }

    return willBlock;
}
Ejemplo n.º 11
0
/*
 * called with scp->rw lock held exclusive
 */
afs_int32
raw_ReadData( cm_scache_t *scp, osi_hyper_t *offsetp,
              afs_uint32 length, char *bufferp, afs_uint32 *readp,
              cm_user_t *userp, cm_req_t *reqp)
{
    long code;
    cm_buf_t *bufp = NULL;
    osi_hyper_t fileLength;
    osi_hyper_t thyper;
    osi_hyper_t lastByte;
    osi_hyper_t bufferOffset;
    long bufIndex, nbytes;
    int sequential = 0;

    /* start by looking up the file's end */
    code = cm_SyncOp(scp, NULL, userp, reqp, 0,
                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
    if (code)
        goto done;

    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);

    /* now we have the entry locked, look up the length */
    fileLength = scp->length;

    /* adjust length down so that it won't go past EOF */
    thyper.LowPart = length;
    thyper.HighPart = 0;
    thyper = LargeIntegerAdd(*offsetp, thyper);	/* where read should end */
    lastByte = thyper;
    if (LargeIntegerGreaterThan(thyper, fileLength)) {
        /* we'd read past EOF, so just stop at fileLength bytes.
        * Start by computing how many bytes remain in the file.
        */
        thyper = LargeIntegerSubtract(fileLength, *offsetp);

        /* if we are past EOF, read 0 bytes */
        if (LargeIntegerLessThanZero(thyper))
            length = 0;
        else
            length = thyper.LowPart;
    }

    *readp = length;

    /* now, copy the data one buffer at a time,
     * until we've filled the request packet
     */
    while (1) {
        /* if we've copied all the data requested, we're done */
        if (length <= 0) break;

        /* otherwise, load up a buffer of data */
        thyper.HighPart = offsetp->HighPart;
        thyper.LowPart = offsetp->LowPart & ~(cm_data.blockSize-1);
        if (!bufp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
            /* wrong buffer */
            if (bufp) {
                buf_Release(bufp);
                bufp = NULL;
            }
            lock_ReleaseWrite(&scp->rw);

            code = buf_Get(scp, &thyper, reqp, 0, &bufp);

            lock_ObtainWrite(&scp->rw);
            if (code) goto done;
            bufferOffset = thyper;

            /* now get the data in the cache */
            while (1) {
                code = cm_SyncOp(scp, bufp, userp, reqp, 0,
                                 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
                if (code)
                    goto done;

		cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);

                if (cm_HaveBuffer(scp, bufp, 0)) break;

                /* otherwise, load the buffer and try again */
                code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
                if (code) break;
            }
            if (code) {
                buf_Release(bufp);
                bufp = NULL;
                goto done;
            }
        }	/* if (wrong buffer) ... */

        /* now we have the right buffer loaded.  Copy out the
         * data from here to the user's buffer.
         */
        bufIndex = offsetp->LowPart & (cm_data.blockSize - 1);

        /* and figure out how many bytes we want from this buffer */
        nbytes = cm_data.blockSize - bufIndex;	/* what remains in buffer */
        if (nbytes > length) nbytes = length;	/* don't go past EOF */

        /* now copy the data */
        memcpy(bufferp, bufp->datap + bufIndex, nbytes);

        /* adjust lengthers, pointers, etc. */
        bufferp += nbytes;
        length -= nbytes;
        thyper.LowPart = nbytes;
        thyper.HighPart = 0;
        *offsetp = LargeIntegerAdd(thyper, *offsetp);
    } /* while 1 */

  done:
    if (bufp)
        buf_Release(bufp);

    if (code == 0 && sequential)
        cm_ConsiderPrefetch(scp, &lastByte, *readp, userp, reqp);

    return code;
}
Ejemplo n.º 12
0
afs_uint32
raw_WriteData( cm_scache_t *scp, osi_hyper_t *offsetp, afs_uint32 length, char *bufferp,
               cm_user_t *userp, cm_req_t *reqp, afs_uint32 *writtenp)
{
    long code = 0;
    long written = 0;
    osi_hyper_t fileLength;	/* file's length at start of write */
    osi_hyper_t minLength;	/* don't read past this */
    afs_uint32 nbytes;		/* # of bytes to transfer this iteration */
    cm_buf_t *bufp = NULL;
    osi_hyper_t thyper;		/* hyper tmp variable */
    osi_hyper_t bufferOffset;
    afs_uint32 bufIndex;	/* index in buffer where our data is */
    int doWriteBack = 0;
    osi_hyper_t writeBackOffset;/* offset of region to write back when I/O is done */
    afs_uint32 writeBackLength;
    DWORD filter = 0;

    /* start by looking up the file's end */
    code = cm_SyncOp(scp, NULL, userp, reqp, 0,
                     CM_SCACHESYNC_NEEDCALLBACK
                      | CM_SCACHESYNC_SETSTATUS
                      | CM_SCACHESYNC_GETSTATUS);
    if (code)
        goto done;

    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_GETSTATUS);

    /* now we have the entry locked, look up the length */
    fileLength = scp->length;
    minLength = fileLength;
    if (LargeIntegerGreaterThan(minLength, scp->serverLength))
        minLength = scp->serverLength;

    /* adjust file length if we extend past EOF */
    thyper.LowPart = length;
    thyper.HighPart = 0;
    thyper = LargeIntegerAdd(*offsetp, thyper);	/* where write should end */
    if (LargeIntegerGreaterThan(thyper, fileLength)) {
        /* we'd write past EOF, so extend the file */
        scp->mask |= CM_SCACHEMASK_LENGTH;
        scp->length = thyper;
        filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE);
    } else
        filter |= FILE_NOTIFY_CHANGE_LAST_WRITE;

    doWriteBack = 1;
    writeBackOffset = *offsetp;
    writeBackLength = length;

    /* now, copy the data one buffer at a time, until we've filled the
     * request packet */
    while (1) {
        /* if we've copied all the data requested, we're done */
        if (length <= 0) break;

        /* otherwise, load up a buffer of data */
        thyper.HighPart = offsetp->HighPart;
        thyper.LowPart = offsetp->LowPart & ~(cm_data.blockSize-1);
        if (!bufp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
            /* wrong buffer */
            if (bufp) {
                lock_ReleaseMutex(&bufp->mx);
                buf_Release(bufp);
                bufp = NULL;
            }
            lock_ReleaseWrite(&scp->rw);

            code = buf_Get(scp, &thyper, reqp, 0, &bufp);
            if (bufp)
                lock_ObtainMutex(&bufp->mx);

            lock_ObtainWrite(&scp->rw);
            if (code)
                goto done;

            bufferOffset = thyper;

            /* now get the data in the cache */
            while (1) {
                code = cm_SyncOp(scp, bufp, userp, reqp, 0,
                                  CM_SCACHESYNC_NEEDCALLBACK
                                  | CM_SCACHESYNC_WRITE
                                  | CM_SCACHESYNC_BUFLOCKED);
                if (code)
                    goto done;

		cm_SyncOpDone(scp, bufp,
			       CM_SCACHESYNC_NEEDCALLBACK
			       | CM_SCACHESYNC_WRITE
			       | CM_SCACHESYNC_BUFLOCKED);

                /* If we're overwriting the entire buffer, or
                 * if we're writing at or past EOF, mark the
                 * buffer as current so we don't call
                 * cm_GetBuffer.  This skips the fetch from the
                 * server in those cases where we're going to
                 * obliterate all the data in the buffer anyway,
                 * or in those cases where there is no useful
                 * data at the server to start with.
                 *
                 * Use minLength instead of scp->length, since
                 * the latter has already been updated by this
                 * call.
                 */
                if (LargeIntegerGreaterThanOrEqualTo(bufp->offset, minLength) ||
                     LargeIntegerEqualTo(*offsetp, bufp->offset) &&
                     (length >= cm_data.blockSize ||
                       LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(*offsetp, ConvertLongToLargeInteger(length)), minLength))) {
                    if (length < cm_data.blockSize
                         && bufp->dataVersion == CM_BUF_VERSION_BAD)
                        memset(bufp->datap, 0,
                                cm_data.blockSize);
                    bufp->dataVersion = scp->dataVersion;
                }

                if (cm_HaveBuffer(scp, bufp, 1)) break;

                /* otherwise, load the buffer and try again */
                lock_ReleaseMutex(&bufp->mx);
                code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
                lock_ReleaseWrite(&scp->rw);
                lock_ObtainMutex(&bufp->mx);
                lock_ObtainWrite(&scp->rw);
                if (code)
                    break;
            }
            if (code) {
                lock_ReleaseMutex(&bufp->mx);
                buf_Release(bufp);
                bufp = NULL;
                goto done;
            }
        }	/* if (wrong buffer) ... */

        /* now we have the right buffer loaded.  Copy out the
         * data from here to the user's buffer.
         */
        bufIndex = offsetp->LowPart & (cm_data.blockSize - 1);

        /* and figure out how many bytes we want from this buffer */
        nbytes = cm_data.blockSize - bufIndex;	/* what remains in buffer */
        if (nbytes > length)
            nbytes = length;	/* don't go past end of request */

        /* now copy the data */
	memcpy(bufp->datap + bufIndex, bufferp, nbytes);
        buf_SetDirty(bufp, reqp, bufIndex, nbytes, userp);

        /* adjust lengthers, pointers, etc. */
        bufferp += nbytes;
        length -= nbytes;
        written += nbytes;
        thyper.LowPart = nbytes;
        thyper.HighPart = 0;
        *offsetp = LargeIntegerAdd(thyper, *offsetp);
    } /* while 1 */

  done:
    if (writtenp)
        *writtenp = written;

    if (bufp) {
        lock_ReleaseMutex(&bufp->mx);
        buf_Release(bufp);
    }

    if (code == 0 && doWriteBack) {
        rock_BkgStore_t *rockp = malloc(sizeof(*rockp));

        if (rockp) {
            code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_ASYNCSTORE);
            if (code == 0) {
                rockp->length = writeBackLength;
                rockp->offset = writeBackOffset;

                lock_ReleaseWrite(&scp->rw);
                cm_QueueBKGRequest(scp, cm_BkgStore, rockp, userp, reqp);
                lock_ObtainWrite(&scp->rw);

                /* rock is freed by cm_BkgDaemon */
            } else {
                free(rockp);
            }
        }
    }

    /* cm_SyncOpDone is called when cm_BkgStore completes */
    return code;
}
Ejemplo n.º 13
0
//Internal Functions
//-------------------------------------------------------------------------
//分析报文
//-------------------------------------------------------------------------
static sys_res gd5100_RmsgAnalyze(void *args)
{
	p_gd5100 p = (t_gd5100 *)args;
	p_dlrcp pRcp = &p->parent;
	uint8_t *pTemp;
#if DLRCP_ZIP_ENABLE
	uint_t nLen;
	int nDelen;
#endif
	p_gd5100_header pH;

	chl_RecData(pRcp->chl, pRcp->rbuf, OS_TICK_MS);
	for (; ; buf_Remove(pRcp->rbuf, 1)) {
		for (; ; buf_Remove(pRcp->rbuf, 1)) {
			//不足报文头长度
			if (pRcp->rbuf->len < sizeof(t_gd5100_header))
				return SYS_R_ERR;
#if DLRCP_ZIP_ENABLE
			if (pRcp->zip) {
				pTemp = pRcp->rbuf->p;
				if ((pTemp[0] == 0x88) && (pTemp[4] == 0xFF)) {
					nLen = (pTemp[2] << 8) | pTemp[3];
					if (pRcp->rbuf->len < (nLen + 5))
						return SYS_R_ERR;
					if (pTemp[nLen + 4] == 0x77) {
						nDelen = DeData(pTemp, nLen + 5);
						if (nDelen > 0) {
							buf_Remove(pRcp->rbuf, nLen + 5);
							buf_Push(pRcp->rbuf, RecvBuf, nDelen);
						}
					}
				}
			}
#endif
			pH = (p_gd5100_header)pRcp->rbuf->p;
			if ((pH->sc1 == 0x68) && (pH->sc2 == 0x68)) {
				if (pH->len > GD5100_DATA_SIZE)
					continue;
				//收到报文头
				if (pRcp->rcvtime == 0)
					pRcp->rcvtime = rtc_GetTimet();
				break;
			}
		}
		//不足长度
		if (pRcp->rbuf->len < (sizeof(t_gd5100_header) + pH->len + 2)) {
			if (((uint16_t)rtc_GetTimet() - pRcp->rcvtime) < 10)
				return SYS_R_ERR;
			pRcp->rcvtime = 0;
			continue;
		}
		pRcp->rcvtime = 0;
		pTemp = pRcp->rbuf->p + sizeof(t_gd5100_header) + pH->len;
		//CS
		if (cs8(pRcp->rbuf->p, sizeof(t_gd5100_header) + pH->len) != *pTemp++)
			continue;
		//结束符
		if (*pTemp != 0x16)
			continue;
		//接收到报文
		p->rmsg->msta = pH->msta;
		p->rmsg->rtua = pH->rtua;
		p->rmsg->terid = pH->terid;
		p->rmsg->fseq = pH->fseq;
		p->rmsg->iseq = pH->iseq;
		p->rmsg->code = pH->code;
		p->rmsg->abn = pH->abn;
		p->rmsg->dir = pH->dir;
		buf_Release(p->rmsg->data);
		buf_Push(p->rmsg->data, pRcp->rbuf->p + sizeof(t_gd5100_header), pH->len);
		buf_Remove(pRcp->rbuf, sizeof(t_gd5100_header) + pH->len + 2);
		return SYS_R_OK;
	}
}
Ejemplo n.º 14
0
sys_res gdfts_Handler(buf bIn, buf bOut)
{
	sys_res res = SYS_R_ERR;
	uint_t nCode, nIsReset = 0;
	uint8_t *pData;
	adr_t adr = upd_DataDev.tbl[0].start;
	gdfts pFts = {0};
	p_gdfts_header pH;
	os_que que;

	if (bOut->len)
		buf_Release(bOut);
	nCode = bIn->p[0] & 0x3F;
	pH = (p_gdfts_header)&bIn->p[1];
	if (pH->id != GDFTS_ID_SELF) {
		//Transceiver
		if (os_que_Send(QUE_EVT_GDFTS_TRANS, NULL, bIn->p, bIn->len, GDFTS_TRANS_TMO) == SYS_R_OK)
			if ((que = os_que_Wait(QUE_EVT_GDFTS_RESPOND, NULL, GDFTS_TRANS_TMO)) != NULL) {
				buf_Push(bOut, que->data->b->p, que->data->b->len);
				os_que_Release(que);
				res = SYS_R_OK;
			}
		if (res != SYS_R_OK) {
			buf_PushData(bOut, nCode | GDFTS_CODE_ERR, 1);
			buf_PushData(bOut, crc16(bOut->p, bOut->len), 2);
		}
		return SYS_R_OK;
	}
	switch (nCode) {
	case GDFTS_CODE_TRANS:
		if (memcmp(gdfts_Pwd, pH->pwd, sizeof(gdfts_Pwd)) == 0) {
			pData = (uint8_t *)(pH + 1);
			if (pH->cnt) {
				if (sfs_Read(upd_SfsDev, pH->id, pFts) == SYS_R_OK)
					if (pFts->cnt == pH->cnt)
						if (flash_Program(upd_DataDev.dev, adr + IAP_HEADER_SIZE + pFts->reced, pData, pH->len) == SYS_R_OK) {
							pFts->cnt += 1;
							pFts->reced += pH->len;
							if (pFts->reced < pFts->len) {
								sfs_Write(upd_SfsDev, pH->id, pFts, sizeof(gdfts));
								res = SYS_R_OK;
							} else if (pFts->crc == crc16((uint8_t *)(adr + IAP_HEADER_SIZE), pFts->len)) {
								t_iap xIap = {0};
								xIap.magic1 = IAP_MAGICWORD_1;
								xIap.magic2 = IAP_MAGICWORD_2;
								xIap.dest = INTFLASH_ADR_BASE + BOOTLOADER_SIZE;
								xIap.len = pFts->len;
								xIap.id = pH->id;
								xIap.crc = pFts->crc;
								sfs_Delete(upd_SfsDev, pH->id);
								if (flash_Program(upd_DataDev.dev, adr, &xIap, sizeof(xIap)) == SYS_R_OK) {
									nIsReset = 1;
									res = SYS_R_OK;
								}
							}
						}
			} else {
				res = SYS_R_OK;
				if ((pH->restart) || (sfs_Read(upd_SfsDev, pH->id, pFts) != SYS_R_OK)) {
					gdfts_DataFormat();
					pFts->cnt = 1;
					pFts->reced = 0;
					memcpy(&pFts->len, pData, sizeof(pFts->len));
					memcpy(&pFts->crc, pData + sizeof(pFts->len), sizeof(pFts->crc));
					res = sfs_Write(upd_SfsDev, pH->id, pFts, sizeof(gdfts));
				}
			}
		}
		if (res == SYS_R_OK)
			gdfts_Response(bOut, nCode | GDFTS_CODE_OK, pH, pFts);
		else
			gdfts_Response(bOut, nCode | GDFTS_CODE_ERR, pH, pFts);
		break;
	case GDFTS_CODE_ABORT:
		if (memcmp(gdfts_Pwd, pH->pwd, sizeof(gdfts_Pwd)) == 0)
			res = sfs_Delete(upd_SfsDev, pH->id);
		if (res == SYS_R_OK)
			nCode |= GDFTS_CODE_OK;
		else
			nCode |= GDFTS_CODE_ERR;
		buf_PushData(bOut, nCode, 1);
		buf_PushData(bOut, pH->id, 2);
		buf_PushData(bOut, crc16(bOut->p, bOut->len), 2);
		break;
	case GDFTS_CODE_INIT:
		if (memcmp(gdfts_Pwd, pH->pwd, sizeof(gdfts_Pwd)) == 0)
			if ((res = gdfts_DataFormat()) == SYS_R_OK)
				if ((res = sfs_Init(upd_SfsDev)) == SYS_R_OK)
					res = sfs_Write(upd_SfsDev, GDFTS_MAGIC_INIT, NULL, 0);
		if (res == SYS_R_OK)
			nCode |= GDFTS_CODE_OK;
		else
			nCode |= GDFTS_CODE_ERR;
		buf_PushData(bOut, nCode, 1);
		buf_PushData(bOut, pH->id, 2);
		buf_PushData(bOut, crc16(bOut->p, bOut->len), 2);
		break;
	default:
		break;
	}
	if (nIsReset)
		return SYS_R_RESET;
	return SYS_R_OK;
}
Ejemplo n.º 15
0
long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op,
               cm_user_t *userp, long *writtenp)
{
    long code = 0;
    long written = 0;
    osi_hyper_t fileLength;	/* file's length at start of write */
    osi_hyper_t minLength;	/* don't read past this */
    afs_uint32 nbytes;		/* # of bytes to transfer this iteration */
    cm_buf_t *bufferp;
    osi_hyper_t thyper;		/* hyper tmp variable */
    osi_hyper_t bufferOffset;
    afs_uint32 bufIndex;	/* index in buffer where our data is */
    int doWriteBack;
    osi_hyper_t writeBackOffset;/* offset of region to write back when
    * I/O is done */
    DWORD filter = 0;
    cm_req_t req;

    cm_InitReq(&req);

    bufferp = NULL;
    doWriteBack = 0;

    lock_ObtainWrite(&scp->rw);

    /* start by looking up the file's end */
    code = cm_SyncOp(scp, NULL, userp, &req, 0,
                     CM_SCACHESYNC_NEEDCALLBACK
                     | CM_SCACHESYNC_SETSTATUS
                     | CM_SCACHESYNC_GETSTATUS);
    if (code)
        goto done;

    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_GETSTATUS);

#if 0
    /* make sure we have a writable FD */
    if (!(fidp->flags & SMB_FID_OPENWRITE)) {
        code = CM_ERROR_BADFDOP;
        goto done;
    }
#endif

    /* now we have the entry locked, look up the length */
    fileLength = scp->length;
    minLength = fileLength;
    if (LargeIntegerGreaterThan(minLength, scp->serverLength))
        minLength = scp->serverLength;

    /* adjust file length if we extend past EOF */
    thyper.LowPart = count;
    thyper.HighPart = 0;
    thyper = LargeIntegerAdd(offset, thyper);	/* where write should end */
    if (LargeIntegerGreaterThan(thyper, fileLength)) {
        /* we'd write past EOF, so extend the file */
        scp->mask |= CM_SCACHEMASK_LENGTH;
        scp->length = thyper;
        filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE);
    } else
        filter |= FILE_NOTIFY_CHANGE_LAST_WRITE;

    /* now, if the new position (thyper) and the old (offset) are in
     * different storeback windows, remember to store back the previous
     * storeback window when we're done with the write.
     */
    if ((thyper.LowPart & (-cm_chunkSize)) !=
            (offset.LowPart & (-cm_chunkSize))) {
        /* they're different */
        doWriteBack = 1;
        writeBackOffset.HighPart = offset.HighPart;
        writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize);
    }

    *writtenp = count;

    /* now, copy the data one buffer at a time, until we've filled the
     * request packet */
    while (1) {
        /* if we've copied all the data requested, we're done */
        if (count <= 0) break;

        /* handle over quota or out of space */
        if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) {
            *writtenp = written;
            break;
        }

        /* otherwise, load up a buffer of data */
        thyper.HighPart = offset.HighPart;
        thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1);
        if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
            /* wrong buffer */
            if (bufferp) {
                lock_ReleaseMutex(&bufferp->mx);
                buf_Release(bufferp);
                bufferp = NULL;
            }
            lock_ReleaseWrite(&scp->rw);

            code = buf_Get(scp, &thyper, &bufferp);

            lock_ObtainMutex(&bufferp->mx);
            lock_ObtainWrite(&scp->rw);
            if (code)
                goto done;

            bufferOffset = thyper;

            /* now get the data in the cache */
            while (1) {
                code = cm_SyncOp(scp, bufferp, userp, &req, 0,
                                 CM_SCACHESYNC_NEEDCALLBACK
                                 | CM_SCACHESYNC_WRITE
                                 | CM_SCACHESYNC_BUFLOCKED);
                if (code)
                    goto done;

                cm_SyncOpDone(scp, bufferp,
                              CM_SCACHESYNC_NEEDCALLBACK
                              | CM_SCACHESYNC_WRITE
                              | CM_SCACHESYNC_BUFLOCKED);

                /* If we're overwriting the entire buffer, or
                 * if we're writing at or past EOF, mark the
                 * buffer as current so we don't call
                 * cm_GetBuffer.  This skips the fetch from the
                 * server in those cases where we're going to
                 * obliterate all the data in the buffer anyway,
                 * or in those cases where there is no useful
                 * data at the server to start with.
                 *
                 * Use minLength instead of scp->length, since
                 * the latter has already been updated by this
                 * call.
                 */
                if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength) ||
                        LargeIntegerEqualTo(offset, bufferp->offset) &&
                        (count >= buf_bufferSize ||
                         LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(offset, ConvertLongToLargeInteger(count)), minLength))) {
                    if (count < buf_bufferSize
                            && bufferp->dataVersion == -1)
                        memset(bufferp->datap, 0,
                               buf_bufferSize);
                    bufferp->dataVersion = scp->dataVersion;
                }

                if (cm_HaveBuffer(scp, bufferp, 1)) break;

                /* otherwise, load the buffer and try again */
                lock_ReleaseMutex(&bufferp->mx);
                code = cm_GetBuffer(scp, bufferp, NULL, userp,
                                    &req);
                lock_ReleaseWrite(&scp->rw);
                lock_ObtainMutex(&bufferp->mx);
                lock_ObtainWrite(&scp->rw);
                if (code)
                    break;
            }
            if (code) {
                lock_ReleaseMutex(&bufferp->mx);
                buf_Release(bufferp);
                bufferp = NULL;
                goto done;
            }
        }	/* if (wrong buffer) ... */

        /* now we have the right buffer loaded.  Copy out the
         * data from here to the user's buffer.
         */
        bufIndex = offset.LowPart & (buf_bufferSize - 1);

        /* and figure out how many bytes we want from this buffer */
        nbytes = buf_bufferSize - bufIndex;	/* what remains in buffer */
        if (nbytes > count)
            nbytes = count;	/* don't go past end of request */

        /* now copy the data */
        memcpy(bufferp->datap + bufIndex, op, nbytes);
        buf_SetDirty(bufferp, bufIndex, nbytes, userp);

        /* adjust counters, pointers, etc. */
        op += nbytes;
        count -= nbytes;
        written += nbytes;
        thyper.LowPart = nbytes;
        thyper.HighPart = 0;
        offset = LargeIntegerAdd(thyper, offset);
    } /* while 1 */

done:
    lock_ReleaseWrite(&scp->rw);
    if (bufferp) {
        lock_ReleaseMutex(&bufferp->mx);
        buf_Release(bufferp);
    }

    if (code == 0 && doWriteBack) {
        lock_ObtainWrite(&scp->rw);
        code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
        lock_ReleaseWrite(&scp->rw);
        if (code == 0)
            cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
                               writeBackOffset.HighPart, cm_chunkSize, 0, userp);
    }

    /* cm_SyncOpDone is called when cm_BkgStore completes */
    return code;
}