LPCUSBSIO_API int32_t I2C_CancelAllRequest(LPC_HANDLE handle) { LPCUSBSIO_I2C_Ctrl_t *dev = (LPCUSBSIO_I2C_Ctrl_t *) handle; uint32_t lMapLenght = 0x00, i; LPCUSBSIO_Request_t** lRequest = NULL; void* Notifier = NULL; framework_LockMutex(dev->RequestMapLock); //1rst call => we get map lenght map_getAll(dev->request_map, NULL, (int*)&lMapLenght); lRequest = framework_AllocMem(lMapLenght * sizeof(LPCUSBSIO_Request_t)); //2nd call => we get all object in map map_getAll(dev->request_map, (void **) lRequest, (int*) &lMapLenght); for (i = 0x00; i < lMapLenght; i++) { //Cancel request if (NULL != (*lRequest)[i].notifier) { (*lRequest)[i].status = LPCUSBSIO_REQ_CANCELED; Notifier = (*lRequest)[i].notifier; framework_LockMutex(Notifier); framework_NotifyMutex(Notifier, 0); framework_UnlockMutex(Notifier); Notifier = NULL; } } framework_FreeMem(lRequest); framework_UnlockMutex(dev->RequestMapLock); return 0; }
void* getNotifier(LPCUSBSIO_I2C_Ctrl_t * dev) { CONTAINER_STATUS lContainerStatus = CONTAINER_SUCCESS; uint32_t size = 0x00; void* Notifier = NULL; if(NULL != dev) { framework_LockMutex(dev->NotifierContainerLock); if(NULL == dev->NotifierContainer) { lContainerStatus = container_create(&dev->NotifierContainer, 2); } if (CONTAINER_SUCCESS == lContainerStatus) { lContainerStatus = container_size(dev->NotifierContainer, &size); if(0x00 == size) { framework_CreateMutex(&Notifier); } else { container_remove(dev->NotifierContainer, 0x00, &Notifier); } } framework_UnlockMutex(dev->NotifierContainerLock); } return Notifier; }
void* thread_object_func(void* obj) { tLinuxThread_t *linuxThread = (tLinuxThread_t *)obj; void *res = NULL; framework_LockMutex(linuxThread->mutexCanDelete); res = linuxThread->threadedFunc(linuxThread->ctx); framework_UnlockMutex(linuxThread->mutexCanDelete); return res; }
void framework_JoinThread(void * threadHandle) { tLinuxThread_t *linuxThread = (tLinuxThread_t*)threadHandle; if (pthread_self() != linuxThread->thread) { // Will cause block if thread still running !!! framework_LockMutex(linuxThread->mutexCanDelete); framework_UnlockMutex(linuxThread->mutexCanDelete); // Thread now just ends up ! } }
void FreeNotifier(LPCUSBSIO_I2C_Ctrl_t * dev, void* Notifier) { if(NULL != dev) { framework_LockMutex(dev->NotifierContainerLock); if(NULL != dev->NotifierContainer && NULL != Notifier) { container_add(dev->NotifierContainer, Notifier); } framework_UnlockMutex(dev->NotifierContainerLock); } }
void framework_NotifyMutex(void * mutexHandle, uint8_t needLock) { tLinuxMutex_t *mutex = (tLinuxMutex_t*)mutexHandle; if (needLock) { framework_LockMutex(mutexHandle); } pthread_cond_broadcast(mutex->cond); if (needLock) { framework_UnlockMutex(mutexHandle); } }
void framework_WaitMutex(void * mutexHandle, uint8_t needLock) { tLinuxMutex_t *mutex = (tLinuxMutex_t*)mutexHandle; if (needLock) { framework_LockMutex(mutexHandle); } pthread_cond_wait(mutex->cond,mutex->lock); if (needLock) { framework_UnlockMutex(mutexHandle); } }
LPCUSBSIO_API int32_t I2C_Close(LPC_HANDLE handle) { LPCUSBSIO_I2C_Ctrl_t *dev = (LPCUSBSIO_I2C_Ctrl_t *) handle; uint8_t inPacket[HID_I2C_PACKET_SZ + 1]; if (validHandle(handle) == 0) { return LPCUSBSIO_ERR_BAD_HANDLE; } I2C_SendRequest(dev, HID_I2C_REQ_DEINIT_PORT, NULL, 0, inPacket, sizeof(inPacket)); /*Shutdown reader thread*/ dev->thread_exit = 0x01; /*Close remote dev handle : all pending request are canceled*/ hid_close(dev->hidDev); /*Wait End of reader thread & clean up*/ framework_JoinThread(dev->ResponsethreadHandle); framework_DeleteThread(dev->ResponsethreadHandle); dev->ResponsethreadHandle = NULL; /*redaer thread is not running so we notify all pending request*/ I2C_CancelAllRequest(handle); g_Ctrl.devInfoList = NULL; ReleaseNotifier(dev); framework_DeleteMutex(dev->NotifierContainerLock); dev->NotifierContainerLock = NULL; framework_LockMutex(dev->RequestMapLock); map_destroy(dev->request_map); dev->request_map = NULL; framework_UnlockMutex(dev->RequestMapLock); framework_DeleteMutex(dev->RequestMapLock); dev->RequestMapLock = NULL; framework_DeleteMutex(dev->SendLock); dev->SendLock = NULL; freeDevice(dev); return LPCUSBSIO_OK; }
void ReleaseNotifier(LPCUSBSIO_I2C_Ctrl_t * dev) { void* Notifier = NULL; if(NULL != dev) { framework_LockMutex(dev->NotifierContainerLock); if(NULL != dev->NotifierContainer) { do { container_remove(dev->NotifierContainer, 0x00, &Notifier); if(NULL != Notifier) { framework_DeleteMutex(Notifier); Notifier = NULL; } }while(NULL != Notifier); container_delete(dev->NotifierContainer); dev->NotifierContainer = NULL; } framework_UnlockMutex(dev->NotifierContainerLock); } }
static int32_t I2C_SendRequest(LPCUSBSIO_I2C_Ctrl_t *dev, uint8_t req, uint8_t* dataOut, uint32_t dataOutLen, uint8_t* dataIn, uint32_t dataInLen) { int32_t res = 0; static uint32_t ReqIndice = 0x00; STATUS lMapStatus = SUCCESS; uint8_t outPacket[HID_I2C_PACKET_SZ + 1]; HID_I2C_OUT_REPORT_T *pOut; LPCUSBSIO_Request_t lRequest; uint32_t pos = 0x00; uint32_t offset = HID_I2C_HEADER_SZ + 1; lRequest.outPacket = dataOut; lRequest.outPacketLen = dataOutLen; lRequest.inPacket = dataIn; lRequest.inPacketLen = dataInLen; lRequest.status = LPCUSBSIO_OK; pOut = (HID_I2C_OUT_REPORT_T *) &outPacket[1]; pOut->sesId = dev->sesionId; pOut->transId = lRequest.transId = ReqIndice++; pOut->req = req; pOut->length = HID_I2C_HEADER_SZ + dataOutLen; framework_LockMutex(dev->RequestMapLock); lMapStatus = map_add(dev->request_map, (void*) (intptr_t) lRequest.transId, (void*) &lRequest); framework_UnlockMutex(dev->RequestMapLock); if(SUCCESS == lMapStatus) { //framework_CreateMutex(&lRequest.notifier); lRequest.notifier = getNotifier(dev); framework_LockMutex(lRequest.notifier); framework_LockMutex(dev->SendLock); //do //{ outPacket[0] = 0; if(lRequest.outPacket != NULL) memcpy(&outPacket[offset], lRequest.outPacket + pos, HID_I2C_PACKET_SZ + 1 - offset); res = hid_write(dev->hidDev, outPacket, HID_I2C_PACKET_SZ + 1); // if (HID_I2C_PACKET_SZ + 1 == res) // { // pos += HID_I2C_PACKET_SZ - offset + 1; // offset = 0x01; // } //} while (pos < len); framework_UnlockMutex(dev->SendLock); if(0x00 < res) { framework_WaitMutex(lRequest.notifier, 0); framework_UnlockMutex(lRequest.notifier); res = lRequest.status; } else { framework_UnlockMutex(lRequest.notifier); res = LPCUSBSIO_ERR_HID_LIB; } framework_LockMutex(dev->RequestMapLock); map_remove(dev->request_map, (void*) (intptr_t) lRequest.transId); framework_UnlockMutex(dev->RequestMapLock); FreeNotifier(dev, lRequest.notifier); //framework_DeleteMutex(lRequest.notifier); lRequest.notifier = NULL; } else { res = LPCUSBSIO_ERR_HID_LIB; } return res; }
static void* WaitRequestResponse(void* pContext) { LPCUSBSIO_I2C_Ctrl_t * dev = pContext; HID_I2C_IN_REPORT_T *pIn; uint8_t inPacket[HID_I2C_PACKET_SZ + 1]; int32_t res = 0; LPCUSBSIO_Request_t* lRequest; STATUS lMapStatus = SUCCESS; void* Notifier = NULL; uint32_t ReadIndex = 0x00; uint32_t lenght = 0x00; while (0x01 != dev->thread_exit) { ReadIndex = 0x00; res = hid_read_timeout(dev->hidDev, inPacket, sizeof(inPacket), LPCUSBSIO_READ_TMO); if (res > 0) { pIn = (HID_I2C_IN_REPORT_T *) &inPacket[0]; framework_LockMutex(dev->RequestMapLock); lMapStatus = map_get(dev->request_map, (void*) (intptr_t) pIn->transId, (void**) &lRequest); framework_UnlockMutex(dev->RequestMapLock); if(SUCCESS == lMapStatus) { ReadIndex += HID_I2C_PACKET_SZ; /* check reponse received from LPC */ lenght = pIn->length; memcpy(lRequest->inPacket, inPacket, HID_I2C_PACKET_SZ); while (ReadIndex < lenght) { res = hid_read_timeout(dev->hidDev, inPacket, sizeof(inPacket), LPCUSBSIO_READ_TMO); if (res > 0) { memcpy(&lRequest->inPacket[ReadIndex], inPacket, HID_I2C_PACKET_SZ); ReadIndex += HID_I2C_PACKET_SZ; } } pIn = (HID_I2C_IN_REPORT_T *)&lRequest->inPacket[0]; Notifier = lRequest->notifier; /* update status */ res = ConvertResp(pIn->resp); lRequest->status = res; lRequest->inPacketLen = HID_I2C_PACKET_SZ + 1; //memcpy(lRequest->inPacket, inPacket, (HID_I2C_PACKET_SZ + 1)); framework_LockMutex(Notifier); framework_NotifyMutex(Notifier, 0); framework_UnlockMutex(Notifier); Notifier = NULL; } else { /*Transition ID received form the chip not recognized !!!!!! why ??????*/ //TODO : define the behaviour in this case res = LPCUSBSIO_ERR_HID_LIB; } } else if (res == 0) { res = LPCUSBSIO_ERR_TIMEOUT; } else { } } return NULL; }