/* * hal_hci_restartReceiver - Signal the Receiver thread to restart the receive process. * This function should be called only after one of the * Receive callbacks returned PENDING (usually when buffer memory is exhausted). * Restart should be triggered when buffer becomes available. * * Parameters: * hHalHci - handle of HalHci * * Return Code: None */ void hal_hci_restartReceiver (handle_t hHalHci) { tHalHci *pHalHci = (tHalHci*)hHalHci; /* Signal semaphore that a buffer is avialable */ signalSem (pHalHci->hMcpf, &pHalHci->tSemBufAvail); }
void *counter(void *threadid) { long i, max = MAX_COUNT/NUM_THREADS; for (i=0; i < max; i++){ if(!sem){ //Obtiene semáforo obtenerSem(&sem); } waitSem(sem); count++; signalSem(sem); usleep(1); } pthread_exit(NULL); }
/** * \fn HAL_ST_Destroy * \brief Destroy the HAL ST object * */ EMcpfRes HAL_ST_Destroy (handle_t hHalSt) { THalStObj *pHalSt = (THalStObj *) hHalSt; /* Release all the thread waiting for this semaphore before deleting it. */ signalSem (pHalSt->hMcpf, &pHalSt->tSem); /* Destroy the semaphore */ if ( sem_destroy(&pHalSt->tSem) < NUMBER_ZERO) { MCPF_REPORT_ERROR (pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("sem_destroy failed!\n")); return RES_ERROR; } mcpf_mem_free (pHalSt->hMcpf, pHalSt); return RES_OK; }
/* * hal_hci_CloseSocket - close raw HCI socket and free all aloocated resources (memory, thread) * * Parameters: * hHalHci - handle of HalHci * * Return Code: HAL_HCI_STATUS_SUCCESS */ eHalHciStatus hal_hci_CloseSocket(handle_t hHalHci) { tHalHci *pHalHci = (tHalHci*)hHalHci; MCPF_Assert(pHalHci); /* Release all the thread waiting for this semaphore before deleting it. */ signalSem (pHalHci->hMcpf, &pHalHci->tSemBufAvail); close(pHalHci->fd); waitForSem(pHalHci->hMcpf, &pHalHci->tSemRxThreadClose); pthread_mutex_destroy(&pHalHci->opcodeLock); sem_destroy(&pHalHci->tSemBufAvail); sem_destroy(&pHalHci->tSemRxThreadClose); free(pHalHci); return HAL_HCI_STATUS_SUCCESS; }
/* * Hace el signal del semaforo encargado de la exclusion mutua */ void signalSemaforo() { signalSem(semaforo); }
void mi_signalSem() { signalSem(semaforo); }
/* * Socket receiver thread. * This thread waits for received traffic. * upon Invokation, it should receive the hci handle with all relevant parameters * Note that RX filter is already initated (from the open function) * RX process verify he validity of received packet before calling the relevant client callback * (command complete or rx callback) */ static handle_t hal_hci_ReceiverThread(handle_t hHalHci) { tHalHci *pHalHci = (tHalHci*)hHalHci; int ret = HAL_HCI_STATUS_SUCCESS, len; McpU8 buf[HAL_HCI_MAX_FRAME_SIZE]; McpU8 pktType, evtType; /* Identify ! */ MCPF_REPORT_INFORMATION(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, (" Enter hal_hci_ReceiverThread")); /* continue running as long as not terminated */ while (1) { struct pollfd p; int n; p.fd = pHalHci->fd; p.events = POLLIN; /* poll device, wait for received data */ while ((n = poll(&p, 1, 500)) == -1) { if (errno == EAGAIN || errno == EINTR) continue; MCPF_REPORT_ERROR(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, ("hal_hci_ReceiverThread: failed to poll device")); ret = HAL_HCI_STATUS_FAILED; goto close; } /* we timeout once in a while - TODO: check if we can elimiate this as we kill the thread on close */ if (0 == n) continue; /* read newly arrived data */ /* TBD: rethink assumption about single arrival */ while ((len = read(pHalHci->fd, buf, sizeof(buf))) < 0) { if (errno == EAGAIN || errno == EINTR) continue; MCPF_REPORT_ERROR(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, ("hal_hci_ReceiverThread: failed to read socket")); ret = HAL_HCI_STATUS_FAILED; goto close; } #ifdef TRAN_DBG for (i = 0; i < len; i++) { MCPF_REPORT_INFORMATION(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, ("buf[%d] = %x", i, buf[i])); } #endif pktType = *buf; evtType = *(buf + 1); #ifdef TRAN_DBG MCPF_REPORT_INFORMATION(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, ("pktType = %x\n", pktType)); #endif /* C ommand Complete Event */ if( (pktType == HAL_HCI_EVENT_PKT) && ((evtType == HAL_HCI_EVT_COMPLETED || evtType == HAL_HCI_EVT_STATUS)) ) { MCPF_REPORT_INFORMATION(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, ("evtType = %x", evtType)); MCPF_REPORT_INFORMATION(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, ("ReceiverThread call the CMD Complete callback" )); pHalHci->opcodeSent = 0; /* If Cmd Cmplt CB returns PENDING --> Rx Congestion */ /* Wait for indication from stack that buffer is avialable */ while ( RES_PENDING == pHalHci->CmdCompleteCallback(pHalHci->hCmdComplete, buf, len, HAL_HCI_STATUS_SUCCESS) ) { waitForSem (pHalHci->hMcpf, &pHalHci->tSemBufAvail); } } else /* Data or A-sync event */ { /* notify stack that RX packet has arrived */ #ifdef TRAN_DBG MCPF_REPORT_INFORMATION(pHalHci->hMcpf, HAL_HCI_MODULE_LOG, ("ReceiverThread call the RX callback" )); #endif /* If Rx CB returns PENDING --> Rx Congestion */ /* Wait for indication from stack that buffer is avialable */ while ( RES_PENDING == pHalHci->RxIndCallabck(pHalHci->hRxInd, buf, len, HAL_HCI_STATUS_SUCCESS) ) { waitForSem (pHalHci->hMcpf, &pHalHci->tSemBufAvail); } } } close: signalSem(pHalHci->hMcpf, &pHalHci->tSemRxThreadClose); pthread_exit((void *)ret); return NULL; }
/** * \fn stThreadFun * \brief ST thread main function * * Thread function waits on and processes OS events (write complete, read ready and management) * * \note * \param pHalSt - pointer to HAL ST object * \return N/A * \sa HAL_ST_Init */ static void *stThreadFun (void * pParam) { THalStObj *pHalSt = (THalStObj *) pParam; fd_set readFds; int iRetCode; EHalStEvent event; /* Identify ! */ MCP_HAL_LOG_SetThreadName("ST"); MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: started, pHalSt=%p\n", __FUNCTION__, pHalSt)); /* This thread would continue running till termination flag is set to TRUE */ pHalSt->terminationFlag = MCP_FALSE; /* signal semaphore the thread is created */ signalSem (pHalSt->hMcpf, &pHalSt->tSem); while (!pHalSt->terminationFlag) { // MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("stThreadFun: Reading data synchronously...\n")); /* initialize file descr. bit sets */ FD_ZERO (&readFds); FD_SET (pHalSt->hOsPort, &readFds); FD_SET (pHalSt->pipeFd[0], &readFds); MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: waiting on select...\n", __FUNCTION__)); iRetCode = select (FD_SETSIZE, &readFds, NULL, NULL, NULL); MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: awaiking from select\n", __FUNCTION__)); if (iRetCode > 0) { /* Determine which file descriptor is ready for read */ if (FD_ISSET(pHalSt->hOsPort, &readFds)) { McpS32 iReadNum, iBytesRead; iRetCode = ioctl (pHalSt->hOsPort, FIONREAD, &pHalSt->iRxAvailNum); MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: ReadReady event, res=%d avail=%d\n", __FUNCTION__, iRetCode, pHalSt->iRxAvailNum)); /* read requested number of bytes */ iReadNum = MIN(pHalSt->iRxReadNum, pHalSt->iRxAvailNum); if (iReadNum > 0) { /* Read received bytes from ST device */ iBytesRead = read (pHalSt->hOsPort, pHalSt->pInData, iReadNum); if (iBytesRead >= 0) { event = HalStEvent_ReadReadylInd; pHalSt->iRxAvailNum -= iBytesRead; pHalSt->iRxRepNum = iBytesRead; pHalSt->iRxReadNum = 0; } else { MCPF_REPORT_ERROR (pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: Read failed, err=%u\n", __FUNCTION__, errno)); event = HalStEvent_Error; } } else { MCPF_REPORT_ERROR (pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: uexpected num zero\n", __FUNCTION__)); event = HalStEvent_Error; } pHalSt->fEventHandlerCb (pHalSt->hHandleCb, event); } if (FD_ISSET(pHalSt->pipeFd[0], &readFds)) { McpU8 uEvt; /* Read management event */ iRetCode = read (pHalSt->pipeFd[0], (void*)&uEvt, 1); if (iRetCode > 0) { switch (uEvt) { case HalStEvent_WriteComplInd: MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: WriteComplete event\n", __FUNCTION__)); pHalSt->fEventHandlerCb (pHalSt->hHandleCb, HalStEvent_WriteComplInd); break; case HalStEvent_Terminate: MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: Exiting the loop\n", __FUNCTION__)); break; case HalStEvent_AwakeRxThread: MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: AwakeRxThread event\n", __FUNCTION__)); break; default: break; } } else { MCPF_REPORT_ERROR(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: pipe read error\n", __FUNCTION__)); } } } else if (iRetCode == 0) { MCPF_REPORT_ERROR(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: select timeout\n", __FUNCTION__)); } else { MCPF_REPORT_ERROR(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: select failed\n", __FUNCTION__)); return NULL; } }/* while */ /* Termination flag is set. Exit from this context */ MCPF_REPORT_DEBUG_CONTROL(pHalSt->hMcpf, HAL_ST_MODULE_LOG, ("%s: exit thread\n",__FUNCTION__)); stPortDestroy (pHalSt); signalSem (pHalSt->hMcpf, &pHalSt->tSem); /* signal semaphore the thread is about to exit */ return NULL; }