int _ExForward_Close(Eip_Session *session,CIP_USINT Priority, CIP_USINT TimeOut_Ticks,CIP_UINT ConnSerialNumber,CIP_UINT OriginatorVendorID, CIP_UDINT OriginatorSerialNumber,BYTE *path,CIP_USINT requestpathsize) { int pathsize=((requestpathsize%2)?(requestpathsize/2+1):(requestpathsize/2)); int requestsize=sizeof(Forward_Close_Request)+2*pathsize; int replysize=0; Forward_Close_Request *request=malloc(requestsize); if (request==NULL) { CIPERROR(Sys_Error,errno,0); return(EX_Error); } memset(request,0,requestsize); request->Priority=Priority;//used to calculate request timeout information request->TimeOut_Ticks=TimeOut_Ticks;//used to calculate request timeout information request->ConnSerialNumber=ConnSerialNumber;// session serial number request->OriginatorVendorID=OriginatorVendorID; request->OriginatorSerialNumber=OriginatorSerialNumber; request->PathSize=pathsize;// size of session path in 16 bits words memcpy(&(request->Path),path,requestpathsize);// padded EPath MR_Reply *reply=_SendMRRequest(session,FORWARD_CLOSE,CM_PATH,sizeof(CM_PATH),request,requestsize,&replysize); free(request); if (reply!=NULL) { LogCip(LogDebug,"_ExForward_Close : reply=%p (%d)\n",reply,replysize); CIPERROR(MR_Error,reply->General_Status,_GetMRExtendedStatus(reply)); int status=reply->General_Status; free(reply); return(status); } else { return(EX_Error); } }
MR_Reply *_ExSendMRRequest(Eip_Session *session,MR_Request *request,int size,int *replysize) { Eip_Item adressitem; Eip_Item dataitem; Encap_Header *reply=NULL; MR_Reply *mrrep=NULL; // adressitem adressitem.Type_Id=ItemId_Null; adressitem.Length=0; // dataitem dataitem.Type_Id=ItemId_UCM; dataitem.Length=size; reply=_SendRRData(session,&adressitem,NULL,&dataitem,request); if (reply==NULL) return(NULL); // no response mrrep=_GetMRReply(reply); if (mrrep!=NULL) { int size=_GetMRReplySize(reply); MR_Reply *result=malloc(size); if (result==NULL) { CIPERROR(Sys_Error,errno,0); free(reply); return(NULL); } memcpy(result,mrrep,size); free(reply); CIPERROR(MR_Error,result->General_Status,_GetMRExtendedStatus(result)); if (replysize!=NULL) *replysize=size; return(result); } else { CIPERROR(EIP_Error,reply->Status,0); free(reply); return(NULL); } }
MR_Reply *_UnconnectedSend(Eip_Session *session,BYTE Priority, CIP_USINT TimeOut_Ticks, MR_Request *MRrequest,int MRrequestsize, BYTE *routepath,CIP_USINT routepathsize,int *replysize) { Unconnected_Send_Request *UCRequest=NULL; MR_Reply *reply=NULL; if ((MRrequest==NULL) && (MRrequestsize<=0)) { CIPERROR(Internal_Error,E_NothingToSend,0); return(NULL); } if ((routepath!=NULL) && (routepathsize>0)) // { int UCRequestsize=sizeof(Unconnected_Send_Request) +MRrequestsize +(MRrequestsize%2) // pad +routepathsize+routepathsize%2; UCRequest=malloc(UCRequestsize); if (UCRequest==NULL) { CIPERROR(Sys_Error,errno,0); return(NULL); }; memset(UCRequest,0,UCRequestsize); void *pos=(void *)(&(UCRequest->MRRequest)); UCRequest->Priority=Priority;//used to calculate request timeout information UCRequest->TimeOut_Ticks=TimeOut_Ticks;//used to calculate request timeout information UCRequest->Request_size=MRrequestsize; memcpy(pos,MRrequest,MRrequestsize); pos+=MRrequestsize+MRrequestsize%2; *((CIP_USINT *)pos)=routepathsize/2; pos+=2*sizeof(CIP_USINT); memcpy(pos,routepath,routepathsize); reply=_SendMRRequest(session,UNCONNECTED_SEND,CM_PATH,sizeof(CM_PATH),UCRequest,UCRequestsize,replysize); free(UCRequest); if (reply!=NULL) { if ((reply->Service!=(UNCONNECTED_SEND+0x80))&&(reply->Service!=(MRrequest->Service+0x80))) { CIPERROR(Internal_Error,E_UnsolicitedMsg,0); free(reply); return(NULL); } else { CIPERROR(MR_Error,reply->General_Status,_GetMRExtendedStatus(reply)); return(reply); } } else return(NULL); } else { reply=_ExSendMRRequest(session,MRrequest,MRrequestsize,replysize); if (reply!=NULL) { if (reply->Service!=(MRrequest->Service+0x80)) { CIPERROR(Internal_Error,E_UnsolicitedMsg,0); free(reply); return(NULL); } else { CIPERROR(MR_Error,reply->General_Status,_GetMRExtendedStatus(reply)); return(reply); } } else return(NULL); } }