/** ************************************************************************************************ * @文件 : Iec10x.c * @作者 : 樊春春 * @版本 : V1.0 * @时间 : 2022/07/09 16:18:42 * @邮箱 : fanchcho@gmail.com * @说明 : ************************************************************************************************ **/ #include "iec10x.h" #include "iec10x_conf.h" #include "iec10x_type.h" PIEC10X_T IEC10X = NULL; iec_16u Iec10x_Sta_Addr = 0; Iec10x_PrioQueue_T Iec10x_PrioQueueArray[IEC10X_PRIO_MAX]; iec_16u IEC10X_Cp16time2a = 0; iec_16u IEC10X_Cp16time2a_V = 0; CP56Time2a_T IEC10X_Cp56time2a; void Iec10x_Lock(void) { #ifdef IEC10XLOCK if (IEC10X->LOCK != NULL) IEC10X->LOCK(); #endif } void Iec10x_UnLock(void) { #ifdef IEC10XLOCK if (IEC10X->UNLOCK != NULL) IEC10X->UNLOCK(); #endif } /**************************************************** * @函数 : IEC10X_InitQ * @作者 : 樊春春 * @功能 : * @入参 : * @说明 : *****************************************************/ void IEC10X_InitQ(void) { iec_8u i; for (i = 0; i < IEC10X_PRIO_MAX; i++) { IEC10X->InitQueue(&Iec10x_PrioQueueArray[i]); } } void IEC10X_ClearQ(void) { iec_8u i; for (i = 0; i < IEC10X_PRIO_MAX; i++) { IEC10X->ClearQueue(&Iec10x_PrioQueueArray[i]); } } iec_8u IEC10X_GetPrio(iec_8u State) { /*Prio from 0~7*/ iec_8u Prio = 0; return Prio; } void IEC10X_Enqueue(iec_8u *EnQBuf, iec_16u Length, iec_8u Prio, void (*IEC10XCallBack)(Iec10x_CallbackArg_T *Arg), Iec10x_CallbackArg_T *CallbackArg) { Iec10x_PrioNode_T *new_p; Iec10x_Lock(); if (Length < IEC10X_HEADER_LENGTH) { LOG("IEC10X_Enqueue,buffer too short \r\n"); goto END; } new_p = (Iec10x_PrioNode_T *)IEC10X->Malloc(sizeof(Iec10x_PrioNode_T) + Length - 1); if (new_p == NULL) { LOG("IEC10X_Enqueue,malloc error \r\n"); goto END; } memcpy(new_p->value, EnQBuf, Length); new_p->Length = Length; /* Prio from 1~8, Array from 0~7*/ if (Prio >= IEC10X_PRIO_MAX) { LOG("IEC10X_Enqueue, error Prio(%d) \r\n", Prio); goto END; } /* Set callback Argument */ new_p->CallBack = IEC10XCallBack; if (CallbackArg != NULL) new_p->CallBackArg = *CallbackArg; new_p->CallBackArg.value = new_p->value; LOG("IEC10X_Enqueue,Prio(%d) elementNum(%d)len(%d)(%d) \r\n", Prio, Iec10x_PrioQueueArray[Prio].ElementNum, Length, new_p->Length); // DumpHEX(new_p->value, new_p->Length); IEC10X->enqueue(&Iec10x_PrioQueueArray[Prio], new_p); END: Iec10x_UnLock(); return; } Iec10x_PrioNode_T *IEC10X_Dequeue(void) { iec_8u Prio; Iec10x_PrioNode_T *ret; Prio = IEC10X->GetPrio(); if (Prio >= 8) { LOG("IEC10X_Dequeue, Error Prio(%d) \r\n", Prio); return 0; } ret = IEC10X->dequeue(&Iec10x_PrioQueueArray[Prio]); if (ret) { Iec10x_PrioQueueArray[Prio].ElementNum--; } LOG("IEC10X_Dequeue(%d) \r\n", ret->Length); return ret; } Iec10x_PrioNode_T *IEC10X_FindQHead(void) { iec_8u Prio; Iec10x_PrioNode_T *ret; Prio = IEC10X->GetPrio(); if (Prio >= 8) { return 0; } ret = IEC10X->FindQHead(&Iec10x_PrioQueueArray[Prio]); return ret; } void Iec10x_Scheduled(int socketfd) { Iec10x_PrioNode_T *DeQNode; DeQNode = IEC10X_Dequeue(); if (DeQNode) { LOG("<<-------------------IEC10X (%d)-------------------->> \r\n", DeQNode->Length); /* call back funtion */ if (DeQNode->CallBack) DeQNode->CallBack(&(DeQNode->CallBackArg)); DumpHEX(DeQNode->value, DeQNode->Length); IEC10X->Send(socketfd, (char *)(DeQNode->value), DeQNode->Length); Iec10x_Lock(); IEC10X->Free(DeQNode); Iec10x_UnLock(); } } /******************************************************************************* * Function Name : RegisterSim900aMoudle * Description : RegisterSim900aMoudle program * Input : None * Output : None * Return : None *******************************************************************************/ iec_32s RegisterIEC10XMoudle(void *_IEC10X) { int ret; if (NULL == _IEC10X) { return -1; } else { IEC10X = (PIEC10X_T)_IEC10X; if (NULL == IEC10X->Init) { return -1; } else { IEC10X_InitQ(); // IEC10X_InitInfo(); ret = IEC10X->Init(); if (0 == ret) { #ifdef IEC101_SET LOG("\r\nRegister \"%s\" IEC101 Success, < HuiXing 2014-2015 > ...\r\n", IEC10X->name); #elif defined(IEC104_SET) LOG("\r\nRegister \"%s\" IEC104 Success, < HuiXing 2014-2015 > ...\r\n", IEC10X->name); #endif } return ret; } } }