📄 ul_iac.c
字号:
/******************************************************************* uLan Communication - uL_DRV - multiplatform uLan driver ul_iac.c - ulan immetiately action command (C) Copyright 1996-2004 by Pavel Pisa - project originator http://cmp.felk.cvut.cz/~pisa (C) Copyright 1996-2004 PiKRON Ltd. http://www.pikron.com (C) Copyright 2002-2004 Petr Smolik The uLan driver project can be used and distributed in compliance with any of next licenses - GPL - GNU Public License See file COPYING for details. - LGPL - Lesser GNU Public License - MPL - Mozilla Public License - and other licenses added by project originator Code can be modified and re-distributed under any combination of the above listed licenses. If contributor does not agree with some of the licenses, he/she can delete appropriate line. WARNING: if you delete all lines, you are not allowed to distribute code or sources in any form. *******************************************************************/#include "ul_drv_iac.h"typedef struct ul_iac_chain { struct ul_iac_chain *prev; struct ul_iac_chain *next; int cmd; int op; unsigned flg; ul_msginfo msginfo; char *ibuff; ul_iac_data iac_data; ul_iac_call_fnc *fnc;} ul_iac_chain;static void add_to_iac_chain(ul_iac_chain **chain,ul_iac_chain *member){ UL_DRV_LOCK_FINI UL_DRV_LOCK; if(!*chain) *chain=member->next=member->prev=member; else { ((volatile ul_iac_chain*)member)->next=*chain; ((volatile ul_iac_chain*)member)->prev=(*chain)->prev; UL_MB(); ((volatile ul_iac_chain*)(*chain))->prev->next=member; ((volatile ul_iac_chain*)(*chain))->prev=member; }; UL_DRV_UNLOCK;};static void del_from_iac_chain(ul_iac_chain **chain,ul_iac_chain *member){ UL_DRV_LOCK_FINI UL_DRV_LOCK; member->next->prev=member->prev; member->prev->next=member->next; if(*chain==member) { if(member->next==member) *chain=NULL; else *chain=member->next; }; UL_DRV_UNLOCK;};int ul_drv_add_iac(ul_drv *udrv,int cmd,int op,ul_iac_call_fnc *fnc,char *buff, unsigned len,unsigned flg,void *ctx){ ul_iac_chain *member; member=(ul_iac_chain*)MALLOC(sizeof(ul_iac_chain)); if(!member) return -ENOMEM; memset(member,0,sizeof(ul_iac_chain)); member->cmd=cmd; member->op=op; member->flg=flg; member->fnc=fnc; member->iac_data.buff=buff; member->iac_data.len=len; member->iac_data.ctx=ctx; add_to_iac_chain(&udrv->iac_chain,member); LOG_IAC("ulan_add_iac : cmd %d\n", member->cmd); return 0;}int ul_drv_del_iac(ul_drv *udrv,int cmd){ ul_iac_chain *member,*next; int r=-1; member=udrv->iac_chain; if(member) do { next=member->next; if(next==udrv->iac_chain) next=NULL; if (member->cmd==cmd) { del_from_iac_chain(&udrv->iac_chain,member); if (member->flg&UL_IAC_BFL_FREEBUFF) FREE(member->iac_data.buff); FREE(member); r=0; break; } } while((member=next)!=NULL); return r;}INLINE int conv_iac_rc(int iac_rc) { if (iac_rc==UL_IAC_RC_PROC) return UL_RC_PROC; if (iac_rc==UL_IAC_RC_FREEMSG) return UL_RC_FREEMSG; return UL_IAC_RC_ERR;}/*******************************************************************//* Message and frame proccessor for user commands */int uld_prmess_iac_s4(ul_drv *udrv, int ret_code){ if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;}; UL_FRET; return udrv->iac_ret_code;};int uld_prmess_iac_s3(ul_drv *udrv, int ret_code){ if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;}; udrv->con_flg=0; /* UL_END */ UL_FCALL2(uld_sndend,uld_prmess_iac_s4); return UL_RC_PROC;};int uld_prmess_iac_s2(ul_drv *udrv, int ret_code){ ul_iac_data *iac_data; if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;}; iac_data=&(udrv->iac_act->iac_data); if (iac_data->len!=iac_data->ptr) { udrv->char_buff=iac_data->buff[iac_data->ptr]; UL_FCALL(*udrv->fnc_sndch); iac_data->ptr++; } else UL_FNEXT(uld_prmess_iac_s3); return UL_RC_PROC;};int uld_prmess_iac_s1(ul_drv *udrv, int ret_code){ udrv->con_sadr=udrv->my_adr; udrv->con_cmd&=0x7f; udrv->con_flg=4; /* UL_BEG */ UL_FCALL2(uld_sndbeg,uld_prmess_iac_s2); return UL_RC_PROC;};int uld_prmess_iac_r5(ul_drv *udrv, int ret_code){ ul_iac_data *iac_data; struct ul_iac_chain *iac_act; if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;}; iac_act=udrv->iac_act; iac_data=&(iac_act->iac_data); UL_FRET; return conv_iac_rc(udrv->iac_act->fnc(udrv,&iac_act->msginfo,iac_act->ibuff,iac_data));};int uld_prmess_iac_r4(ul_drv *udrv, int ret_code){ if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;}; udrv->con_flg=0; /* UL_END */ UL_FCALL2(uld_recend,uld_prmess_iac_r5); return UL_RC_PROC;};int uld_prmess_iac_r3(ul_drv *udrv, int ret_code){ ul_iac_data *iac_data; if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;}; iac_data=&(udrv->iac_act->iac_data); if(!(udrv->char_buff&0xFF00)) { iac_data->buff[iac_data->ptr]=udrv->char_buff; iac_data->ptr++; iac_data->len++; UL_FCALL(*udrv->fnc_recch); return UL_RC_PROC; } UL_FNEXT(uld_prmess_iac_r4); return UL_RC_PROC;}int uld_prmess_iac_r2(ul_drv *udrv, int ret_code){ if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;}; UL_FCALL2(*udrv->fnc_recch,uld_prmess_iac_r3); return UL_RC_PROC;}int uld_prmess_iac_r1(ul_drv *udrv, int ret_code){ udrv->con_flg=8; /* UL_BEG */ UL_FCALL2(uld_recbeg,uld_prmess_iac_r2); return UL_RC_PROC;};int get_iac_op(ul_drv *udrv, uchar cmd){ ul_iac_chain *member,*next; member=udrv->iac_chain; if(member) do { next=member->next; if(next==udrv->iac_chain) next=NULL; if (member->cmd==cmd) { udrv->iac_act=member; return member->op; } } while((member=next)!=NULL); return -1;}int uld_prmess_iac(ul_drv *udrv, int ret_code){ ul_iac_data *iac_data; struct ul_iac_chain *iac_act; ul_mem_blk *mes; int r; ret_code=UL_RC_PROC; mes=udrv->con_message; r=get_iac_op(udrv,udrv->con_cmd); if (r==-1) { UL_FRET; return ret_code; } iac_act=udrv->iac_act; iac_data=&(iac_act->iac_data); iac_act->msginfo.dadr=UL_BLK_HEAD(mes).dadr; iac_act->msginfo.sadr=UL_BLK_HEAD(mes).sadr; iac_act->msginfo.flg=UL_BLK_HEAD(mes).flg; iac_act->msginfo.len=UL_BLK_HEAD(mes).len; if (iac_act->msginfo.len>UL_BLK_SIZE) iac_act->msginfo.len=UL_BLK_SIZE; iac_act->ibuff=UL_BLK_FDATA(mes); switch (r) { case UL_IAC_OP_CALLBACK: ret_code=conv_iac_rc(udrv->iac_act->fnc(udrv,&iac_act->msginfo,iac_act->ibuff,iac_data)); break; case UL_IAC_OP_SNDBUFF: case UL_IAC_OP_SND: if (udrv->con_flg&2) { udrv->iac_ret_code=UL_RC_FREEMSG; iac_data->ptr=0; UL_FNEXT(uld_prmess_iac_s1); if (r==UL_IAC_OP_SND) udrv->iac_ret_code=conv_iac_rc(udrv->iac_act->fnc(udrv,&iac_act->msginfo,iac_act->ibuff,iac_data)); return UL_RC_PROC; } break; case UL_IAC_OP_REC: if (udrv->con_flg&2) { iac_data->ptr=0; iac_data->len=0; UL_FNEXT(uld_prmess_iac_r1); return UL_RC_PROC; } default: break; } UL_FRET; return ret_code;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -