RTDECL(int) RTReqQueueProcess(RTREQQUEUE hQueue, RTMSINTERVAL cMillies)
{
    LogFlow(("RTReqQueueProcess %x\n", hQueue));

    /*
     * Check input.
     */
    PRTREQQUEUEINT pQueue = hQueue;
    AssertPtrReturn(pQueue, VERR_INVALID_HANDLE);
    AssertReturn(pQueue->u32Magic == RTREQQUEUE_MAGIC, VERR_INVALID_HANDLE);

    /*
     * Process loop.
     *
     * We do not repeat the outer loop if we've got an informational status code
     * since that code needs processing by our caller.
     */
    int rc = VINF_SUCCESS;
    while (rc <= VINF_SUCCESS)
    {
        /*
         * Get pending requests.
         */
        PRTREQ pReqs = ASMAtomicXchgPtrT(&pQueue->pReqs, NULL, PRTREQ);
        if (!pReqs)
        {
            ASMAtomicWriteBool(&pQueue->fBusy, false); /* this aint 100% perfect, but it's good enough for now... */
            /** @todo We currently don't care if the entire time wasted here is larger than
             *        cMillies */
            rc = RTSemEventWait(pQueue->EventSem, cMillies);
            if (rc != VINF_SUCCESS)
                break;
            continue;
        }
        ASMAtomicWriteBool(&pQueue->fBusy, true);

        /*
         * Reverse the list to process it in FIFO order.
         */
        PRTREQ pReq = pReqs;
        if (pReq->pNext)
            Log2(("RTReqQueueProcess: 2+ requests: %p %p %p\n", pReq, pReq->pNext, pReq->pNext->pNext));
        pReqs = NULL;
        while (pReq)
        {
            Assert(pReq->enmState == RTREQSTATE_QUEUED);
            Assert(pReq->uOwner.hQueue == pQueue);
            PRTREQ pCur = pReq;
            pReq = pReq->pNext;
            pCur->pNext = pReqs;
            pReqs = pCur;
        }


        /*
         * Process the requests.
         */
        while (pReqs)
        {
            /* Unchain the first request and advance the list. */
            pReq = pReqs;
            pReqs = pReqs->pNext;
            pReq->pNext = NULL;

            /* Process the request */
            rc = rtReqProcessOne(pReq);
            AssertRC(rc);
            if (rc != VINF_SUCCESS)
                break; /** @todo r=bird: we're dropping requests here! Add 2nd queue that can hold them. (will fix when writing a testcase)  */
        }
    }

    LogFlow(("RTReqQueueProcess: returns %Rrc\n", rc));
    return rc;
}
/**
 * Synchronizes one GDT entry (guest -> shadow).
 *
 * @returns VBox strict status code (appropriate for trap handling and GC
 *          return).
 * @retval  VINF_SUCCESS
 * @retval  VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT
 * @retval  VINF_SELM_SYNC_GDT
 *
 * @param   pVM         Pointer to the VM.
 * @param   pVCpu       The current virtual CPU.
 * @param   pCtx        CPU context for the current CPU.
 * @param   iGDTEntry   The GDT entry to sync.
 *
 * @remarks Caller checks that this isn't the LDT entry!
 */
static VBOXSTRICTRC selmRCSyncGDTEntry(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, unsigned iGDTEntry)
{
    Log2(("GDT %04X LDTR=%04X\n", iGDTEntry, CPUMGetGuestLDTR(pVCpu)));

    /*
     * Validate the offset.
     */
    VBOXGDTR GdtrGuest;
    CPUMGetGuestGDTR(pVCpu, &GdtrGuest);
    unsigned offEntry = iGDTEntry * sizeof(X86DESC);
    if (    iGDTEntry >= SELM_GDT_ELEMENTS
        ||  offEntry  >  GdtrGuest.cbGdt)
        return VINF_SUCCESS; /* ignore */

    /*
     * Read the guest descriptor.
     */
    X86DESC Desc;
    int rc = MMGCRamRead(pVM, &Desc, (uint8_t *)(uintptr_t)GdtrGuest.pGdt + offEntry, sizeof(X86DESC));
    if (RT_FAILURE(rc))
    {
        rc = PGMPhysSimpleReadGCPtr(pVCpu, &Desc, (uintptr_t)GdtrGuest.pGdt + offEntry, sizeof(X86DESC));
        if (RT_FAILURE(rc))
        {
            VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
            VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3); /* paranoia */
            /* return VINF_EM_RESCHEDULE_REM; - bad idea if we're in a patch. */
            return VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT;
        }
    }

    /*
     * Check for conflicts.
     */
    RTSEL   Sel = iGDTEntry << X86_SEL_SHIFT;
    Assert(   !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]         & ~X86_SEL_MASK_OFF_RPL)
           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]         & ~X86_SEL_MASK_OFF_RPL)
           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]       & ~X86_SEL_MASK_OFF_RPL)
           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]        & ~X86_SEL_MASK_OFF_RPL)
           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] & ~X86_SEL_MASK_OFF_RPL));
    if (    pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]         == Sel
        ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]         == Sel
        ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]       == Sel
        ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]        == Sel
        ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] == Sel)
    {
        if (Desc.Gen.u1Present)
        {
            Log(("selmRCSyncGDTEntry: Sel=%d Desc=%.8Rhxs: detected conflict!!\n", Sel, &Desc));
            VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
            VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3);
            return VINF_SELM_SYNC_GDT;  /** @todo this status code is ignored, unfortunately. */
        }
        Log(("selmRCSyncGDTEntry: Sel=%d Desc=%.8Rhxs: potential conflict (still not present)!\n", Sel, &Desc));

        /* Note: we can't continue below or else we'll change the shadow descriptor!! */
        /* When the guest makes the selector present, then we'll do a GDT sync. */
        return VINF_SUCCESS;
    }

    /*
     * Convert the guest selector to a shadow selector and update the shadow GDT.
     */
    selmGuestToShadowDesc(pVM, &Desc);
    PX86DESC pShwDescr = &pVM->selm.s.paGdtRC[iGDTEntry];
    //Log(("O: base=%08X limit=%08X attr=%04X\n", X86DESC_BASE(*pShwDescr)), X86DESC_LIMIT(*pShwDescr), (pShwDescr->au32[1] >> 8) & 0xFFFF ));
    //Log(("N: base=%08X limit=%08X attr=%04X\n", X86DESC_BASE(Desc)), X86DESC_LIMIT(Desc), (Desc.au32[1] >> 8) & 0xFFFF ));
    *pShwDescr = Desc;

    /*
     * Detect and mark stale registers.
     */
    VBOXSTRICTRC rcStrict = VINF_SUCCESS;
    PCPUMSELREG  paSReg   = CPUMCTX_FIRST_SREG(pCtx);
    for (unsigned iSReg = 0; iSReg <= X86_SREG_COUNT; iSReg++)
    {
        if (Sel == (paSReg[iSReg].Sel & X86_SEL_MASK_OFF_RPL))
        {
            if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &paSReg[iSReg]))
            {
                if (selmIsSRegStale32(&paSReg[iSReg], &Desc, iSReg))
                {
                    Log(("GDT write to selector in %s register %04X (now stale)\n", g_aszSRegNms[iSReg], paSReg[iSReg].Sel));
                    paSReg[iSReg].fFlags |= CPUMSELREG_FLAGS_STALE;
                    VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3); /* paranoia */
                    /* rcStrict = VINF_EM_RESCHEDULE_REM; - bad idea if we're in a patch. */
                    rcStrict = VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT;
                }
                else if (paSReg[iSReg].fFlags & CPUMSELREG_FLAGS_STALE)
                {
                    Log(("GDT write to selector in %s register %04X (no longer stale)\n", g_aszSRegNms[iSReg], paSReg[iSReg].Sel));
                    paSReg[iSReg].fFlags &= ~CPUMSELREG_FLAGS_STALE;
                }
                else
                    Log(("GDT write to selector in %s register %04X (no important change)\n", g_aszSRegNms[iSReg], paSReg[iSReg].Sel));
            }
            else
                Log(("GDT write to selector in %s register %04X (out of sync)\n", paSReg[iSReg].Sel));
        }
    }

    /** @todo Detect stale LDTR as well? */

    return rcStrict;
}
Example #3
0
void     MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
{
    int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
    Assert(iOff >= 0 && (pciDevIsMsiCapable(pDev) && iOff < pDev->Int.s.u8MsiCapSize));

    Log2(("MsiPciConfigWrite: %d <- %x (%d)\n", iOff, val, len));

    uint32_t uAddr = u32Address;
    bool f64Bit = msiIs64Bit(pDev);

    for (uint32_t i = 0; i < len; i++)
    {
        uint32_t reg = i + iOff;
        uint8_t u8Val = (uint8_t)val;
        switch (reg)
        {
            case 0: /* Capability ID, ro */
            case 1: /* Next pointer,  ro */
                break;
            case VBOX_MSI_CAP_MESSAGE_CONTROL:
                /* don't change read-only bits: 1-3,7 */
                u8Val &= UINT8_C(~0x8e);
                pDev->config[uAddr] = u8Val | (pDev->config[uAddr] & UINT8_C(0x8e));
                break;
            case VBOX_MSI_CAP_MESSAGE_CONTROL + 1:
                /* don't change read-only bit 8, and reserved 9-15 */
                break;
            default:
                if (pDev->config[uAddr] != u8Val)
                {
                    int32_t maskUpdated = -1;

                    /* If we're enabling masked vector, and have pending messages
                       for this vector, we have to send this message now */
                    if (    !f64Bit
                         && (reg >= VBOX_MSI_CAP_MASK_BITS_32)
                         && (reg < VBOX_MSI_CAP_MASK_BITS_32 + 4)
                        )
                    {
                        maskUpdated = reg - VBOX_MSI_CAP_MASK_BITS_32;
                    }
                    if (    f64Bit
                         && (reg >= VBOX_MSI_CAP_MASK_BITS_64)
                         && (reg < VBOX_MSI_CAP_MASK_BITS_64 + 4)
                       )
                    {
                        maskUpdated = reg - VBOX_MSI_CAP_MASK_BITS_64;
                    }

                    if (maskUpdated != -1 && msiIsEnabled(pDev))
                    {
                        uint32_t*  puPending = msiGetPendingBits(pDev);
                        for (int iBitNum = 0; iBitNum < 8; iBitNum++)
                        {
                            int32_t iBit = 1 << iBitNum;
                            uint32_t uVector = maskUpdated*8 + iBitNum;

                            if (msiBitJustCleared(pDev->config[uAddr], u8Val, iBit))
                            {
                                Log(("msi: mask updated bit %d@%x (%d)\n", iBitNum, uAddr, maskUpdated));

                                /* To ensure that we're no longer masked */
                                pDev->config[uAddr] &= ~iBit;
                                if ((*puPending & (1 << uVector)) != 0)
                                {
                                    Log(("msi: notify earlier masked pending vector: %d\n", uVector));
                                    MsiNotify(pDevIns, pPciHlp, pDev, uVector, PDM_IRQ_LEVEL_HIGH);
                                }
                            }
                            if (msiBitJustSet(pDev->config[uAddr], u8Val, iBit))
                            {
                                Log(("msi: mask vector: %d\n", uVector));
                            }
                        }
                    }

                    pDev->config[uAddr] = u8Val;
                }
        }
        uAddr++;
        val >>= 8;
    }
}
Example #4
0
int
udp_attach(PNATState pData, struct socket *so)
{
    struct sockaddr_in *addr;
    struct sockaddr sa_addr;
    socklen_t socklen = sizeof(struct sockaddr);
    int status;
    int opt = 1;

    /* We attaching some olready attched socket ??? */
    Assert(so->so_type == 0);
    if ((so->s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        goto error;
    so->so_sottl = 0;
    so->so_sotos = 0;
    so->so_sodf = -1;
    /*
     * Here, we bind() the socket.  Although not really needed
     * (sendto() on an unbound socket will bind it), it's done
     * here so that emulation of ytalk etc. don't have to do it
     */
    memset(&sa_addr, 0, sizeof(struct sockaddr));
    addr = (struct sockaddr_in *)&sa_addr;
#ifdef RT_OS_DARWIN
    addr->sin_len = sizeof(struct sockaddr_in);
#endif
    addr->sin_family = AF_INET;
    addr->sin_addr.s_addr = pData->bindIP.s_addr;
    fd_nonblock(so->s);
    if (bind(so->s, &sa_addr, sizeof(struct sockaddr_in)) < 0)
    {
        int lasterrno = errno;
        closesocket(so->s);
        so->s = -1;
#ifdef RT_OS_WINDOWS
        WSASetLastError(lasterrno);
#else
        errno = lasterrno;
#endif
        goto error;
    }
    /* success, insert in queue */
    so->so_expire = curtime + SO_EXPIRE;
    /* enable broadcast for later use */
    setsockopt(so->s, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt));
    status = getsockname(so->s, &sa_addr, &socklen);
    Assert(status == 0 && sa_addr.sa_family == AF_INET);
    so->so_hlport = ((struct sockaddr_in *)&sa_addr)->sin_port;
    so->so_hladdr.s_addr = ((struct sockaddr_in *)&sa_addr)->sin_addr.s_addr;

    SOCKET_LOCK_CREATE(so);
    QSOCKET_LOCK(udb);
    insque(pData, so, &udb);
    NSOCK_INC();
    QSOCKET_UNLOCK(udb);
    so->so_type = IPPROTO_UDP;
    return so->s;
error:
    Log2(("NAT: can't create datagramm socket\n"));
    return -1;
}
Example #5
0
/* m->m_data  points at ip packet header
 * m->m_len   length ip packet
 * ip->ip_len length data (IPDU)
 */
void
udp_input(PNATState pData, register struct mbuf *m, int iphlen)
{
    register struct ip *ip;
    register struct udphdr *uh;
    int len;
    struct ip save_ip;
    struct socket *so;
    int ret;
    int ttl;

    LogFlowFunc(("ENTER: m = %p, iphlen = %d\n", m, iphlen));
    ip = mtod(m, struct ip *);
    Log2(("%RTnaipv4 iphlen = %d\n", ip->ip_dst, iphlen));

    udpstat.udps_ipackets++;

    /*
     * Strip IP options, if any; should skip this,
     * make available to user, and use on returned packets,
     * but we don't yet have a way to check the checksum
     * with options still present.
     */
    if (iphlen > sizeof(struct ip))
    {
        ip_stripoptions(m, (struct mbuf *)0);
        iphlen = sizeof(struct ip);
    }

    /*
     * Get IP and UDP header together in first mbuf.
     */
    ip = mtod(m, struct ip *);
    uh = (struct udphdr *)((caddr_t)ip + iphlen);

    /*
     * Make mbuf data length reflect UDP length.
     * If not enough data to reflect UDP length, drop.
     */
    len = RT_N2H_U16((u_int16_t)uh->uh_ulen);
    Assert((ip->ip_len == len));
    Assert((ip->ip_len + iphlen == m_length(m, NULL)));

    if (ip->ip_len != len)
    {
        if (len > ip->ip_len)
        {
            udpstat.udps_badlen++;
            Log3(("NAT: IP(id: %hd) has bad size\n", ip->ip_id));
        }
        m_adj(m, len - ip->ip_len);
        ip->ip_len = len;
    }

    /*
     * Save a copy of the IP header in case we want restore it
     * for sending an ICMP error message in response.
     */
    save_ip = *ip;
    save_ip.ip_len+= iphlen;         /* tcp_input subtracts this */

    /*
     * Checksum extended UDP header and data.
     */
    if (udpcksum && uh->uh_sum)
    {
        memset(((struct ipovly *)ip)->ih_x1, 0, 9);
        ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
#if 0
        /* keep uh_sum for ICMP reply */
        uh->uh_sum = cksum(m, len + sizeof (struct ip));
        if (uh->uh_sum)
        {

#endif
            if (cksum(m, len + iphlen))
            {
                udpstat.udps_badsum++;
                Log3(("NAT: IP(id: %hd) has bad (udp) cksum\n", ip->ip_id));
                goto bad_free_mbuf;
            }
        }
#if 0
    }
#endif

    /*
     *  handle DHCP/BOOTP
     */
    if (uh->uh_dport == RT_H2N_U16_C(BOOTP_SERVER))
    {
        bootp_input(pData, m);
        goto done_free_mbuf;
    }

    LogFunc(("uh src: %RTnaipv4:%d, dst: %RTnaipv4:%d\n", ip->ip_src, RT_H2N_U16_C(uh->uh_sport), ip->ip_dst, RT_H2N_U16_C(uh->uh_dport)));
    if (   pData->fUseHostResolver
        && uh->uh_dport == RT_H2N_U16_C(53)
        && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS))
    {
        struct sockaddr_in dst, src;
        src.sin_addr.s_addr = ip->ip_dst.s_addr;
        src.sin_port = uh->uh_dport;
        dst.sin_addr.s_addr = ip->ip_src.s_addr;
        dst.sin_port = uh->uh_sport;

        slirpMbufTagService(pData, m, CTL_DNS);
        /* udp_output2() expects a pointer to the body of UDP packet. */
        m->m_data += sizeof(struct udpiphdr);
        m->m_len -= sizeof(struct udpiphdr);
        udp_output2(pData, NULL, m, &src, &dst, IPTOS_LOWDELAY);
        LogFlowFuncLeave();
        return;
    }
    /*
     *  handle TFTP
     */
    if (   uh->uh_dport == RT_H2N_U16_C(TFTP_SERVER)
        && CTL_CHECK(ip->ip_dst.s_addr, CTL_TFTP))
    {
        if (pData->pvTftpSessions)
            slirpTftpInput(pData, m);
        goto done_free_mbuf;
    }

    /*
     * Locate pcb for datagram.
     */
    so = udp_last_so;
    if (   so->so_lport != uh->uh_sport
        || so->so_laddr.s_addr != ip->ip_src.s_addr)
    {
        struct socket *tmp;

        for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next)
        {
            if (   tmp->so_lport        == uh->uh_sport
                && tmp->so_laddr.s_addr == ip->ip_src.s_addr)
            {
                so = tmp;
                break;
            }
        }
        if (tmp == &udb)
            so = NULL;
        else
        {
            udpstat.udpps_pcbcachemiss++;
            udp_last_so = so;
        }
    }

    if (so == NULL)
    {
        /*
         * If there's no socket for this packet,
         * create one
         */
        if ((so = socreate()) == NULL)
        {
            Log2(("NAT: IP(id: %hd) failed to create socket\n", ip->ip_id));
            goto bad_free_mbuf;
        }
        if (udp_attach(pData, so) <= 0)
        {
            Log2(("NAT: IP(id: %hd) udp_attach errno = %d (%s)\n",
                        ip->ip_id, errno, strerror(errno)));
            sofree(pData, so);
            goto bad_free_mbuf;
        }

        /*
         * Setup fields
         */
        /* udp_last_so = so; */
        so->so_laddr = ip->ip_src;
        so->so_lport = uh->uh_sport;

        so->so_iptos = ip->ip_tos;

        /*
         * XXXXX Here, check if it's in udpexec_list,
         * and if it is, do the fork_exec() etc.
         */
    }

    so->so_faddr = ip->ip_dst;   /* XXX */
    so->so_fport = uh->uh_dport; /* XXX */
    Assert(so->so_type == IPPROTO_UDP);

    /*
     * DNS proxy
     */
    if (   pData->fUseDnsProxy
        && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS)
        && (uh->uh_dport == RT_H2N_U16_C(53)))
    {
        dnsproxy_query(pData, so, m, iphlen);
        goto done_free_mbuf;
    }

    iphlen += sizeof(struct udphdr);
    m->m_len -= iphlen;
    m->m_data += iphlen;

    ttl = ip->ip_ttl = save_ip.ip_ttl;
    ret = setsockopt(so->s, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl));
    if (ret < 0)
        LogRel(("NAT: Error (%s) occurred while setting TTL(%d) attribute "
                "of IP packet to socket %R[natsock]\n", strerror(errno), ip->ip_ttl, so));

    if (   sosendto(pData, so, m) == -1
        && (   !soIgnorableErrorCode(errno)
            && errno != ENOTCONN))
    {
        m->m_len += iphlen;
        m->m_data -= iphlen;
        *ip = save_ip;
        Log2(("NAT: UDP tx errno = %d (%s) on sent to %RTnaipv4\n",
              errno, strerror(errno), ip->ip_dst));
#if 0
        /* ICMP_SOURCEQUENCH haven't got any effect, the idea here
         * inform guest about the exosting NAT resources with assumption that
         * that guest reduce traffic. But it doesn't work
         */
        if(    errno == EAGAIN
            || errno == EWOULDBLOCK
            || errno == EINPROGRESS
            || errno == ENOTCONN)
            icmp_error(pData, m, ICMP_SOURCEQUENCH, 0, 1, strerror(errno));
        else
#endif
            icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
        so->so_m = NULL;
        LogFlowFuncLeave();
        return;
    }

    if (so->so_m)
        m_freem(pData, so->so_m);   /* used for ICMP if error on sorecvfrom */

    /* restore the orig mbuf packet */
    m->m_len += iphlen;
    m->m_data -= iphlen;
    *ip = save_ip;
    so->so_m = m;         /* ICMP backup */
    LogFlowFuncLeave();
    return;

bad_free_mbuf:
    Log2(("NAT: UDP(id: %hd) datagram to %RTnaipv4 with size(%d) claimed as bad\n",
        ip->ip_id, &ip->ip_dst, ip->ip_len));

done_free_mbuf:
    /* some services like bootp(built-in), dns(buildt-in) and dhcp don't need sockets
     * and create new m'buffers to send them to guest, so we'll free their incomming
     * buffers here.
     */
    m_freem(pData, m);
    LogFlowFuncLeave();
    return;
}
static void ContextThread(LPVOID newContext)
{
	SCONTEXT * threadContext = (SCONTEXT *) newContext;
	int32_t filedes = threadContext->dwClientID;

	Log3(PCSC_LOG_DEBUG, "Thread is started: dwClientID=%d, threadContext @%p",
		threadContext->dwClientID, threadContext);

	while (1)
	{
		struct rxHeader header;
		int32_t ret = MessageReceive(&header, sizeof(header), filedes);

		if (ret != SCARD_S_SUCCESS)
		{
			/* Clean up the dead client */
			Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
			EHTryToUnregisterClientForEvent(filedes);
			goto exit;
		}

		if ((header.command > CMD_ENUM_FIRST)
			&& (header.command < CMD_ENUM_LAST))
			Log3(PCSC_LOG_DEBUG, "Received command: %s from client %d",
				CommandsText[header.command], filedes);

		switch (header.command)
		{
			/* pcsc-lite client/server protocol version */
			case CMD_VERSION:
			{
				struct version_struct veStr;

				READ_BODY(veStr)

				Log3(PCSC_LOG_DEBUG, "Client is protocol version %d:%d",
					veStr.major, veStr.minor);

				veStr.rv = SCARD_S_SUCCESS;

				/* client and server use different protocol */
				if ((veStr.major != PROTOCOL_VERSION_MAJOR)
					|| (veStr.minor != PROTOCOL_VERSION_MINOR))
				{
					Log3(PCSC_LOG_CRITICAL, "Client protocol is %d:%d",
						veStr.major, veStr.minor);
					Log3(PCSC_LOG_CRITICAL, "Server protocol is %d:%d",
						PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR);
					veStr.rv = SCARD_E_NO_SERVICE;
				}

				/* set the server protocol version */
				veStr.major = PROTOCOL_VERSION_MAJOR;
				veStr.minor = PROTOCOL_VERSION_MINOR;

				/* send back the response */
				WRITE_BODY(veStr)
			}
			break;

			case CMD_GET_READERS_STATE:
			{
				/* nothing to read */

#ifdef USE_USB
				/* wait until all readers are ready */
				RFWaitForReaderInit();
#endif

				/* dump the readers state */
				ret = MessageSend(readerStates, sizeof(readerStates), filedes);
			}
			break;

			case CMD_WAIT_READER_STATE_CHANGE:
			{
				struct wait_reader_state_change waStr;

				READ_BODY(waStr)

				/* add the client fd to the list */
				EHRegisterClientForEvent(filedes);

				/* We do not send anything here.
				 * Either the client will timeout or the server will
				 * answer if an event occurs */
			}
			break;

			case CMD_STOP_WAITING_READER_STATE_CHANGE:
			{
				struct wait_reader_state_change waStr;

				READ_BODY(waStr)

				/* add the client fd to the list */
				waStr.rv = EHUnregisterClientForEvent(filedes);

				WRITE_BODY(waStr)
			}
			break;

			case SCARD_ESTABLISH_CONTEXT:
			{
				struct establish_struct esStr;
				SCARDCONTEXT hContext;

				READ_BODY(esStr)

				hContext = esStr.hContext;
				esStr.rv = SCardEstablishContext(esStr.dwScope, 0, 0,
					&hContext);
				esStr.hContext = hContext;

				if (esStr.rv == SCARD_S_SUCCESS)
					esStr.rv = MSGAddContext(esStr.hContext, threadContext);

				WRITE_BODY(esStr)
			}
			break;

			case SCARD_RELEASE_CONTEXT:
			{
				struct release_struct reStr;

				READ_BODY(reStr)

				reStr.rv = SCardReleaseContext(reStr.hContext);

				if (reStr.rv == SCARD_S_SUCCESS)
					reStr.rv = MSGRemoveContext(reStr.hContext, threadContext);

				WRITE_BODY(reStr)
			}
			break;

			case SCARD_CONNECT:
			{
				struct connect_struct coStr;
				SCARDHANDLE hCard;
				DWORD dwActiveProtocol;

				READ_BODY(coStr)

				hCard = coStr.hCard;
				dwActiveProtocol = coStr.dwActiveProtocol;

				coStr.rv = SCardConnect(coStr.hContext, coStr.szReader,
					coStr.dwShareMode, coStr.dwPreferredProtocols,
					&hCard, &dwActiveProtocol);

				coStr.hCard = hCard;
				coStr.dwActiveProtocol = dwActiveProtocol;

				if (coStr.rv == SCARD_S_SUCCESS)
					coStr.rv = MSGAddHandle(coStr.hContext, coStr.hCard,
						threadContext);

				WRITE_BODY(coStr)
			}
			break;

			case SCARD_RECONNECT:
			{
				struct reconnect_struct rcStr;
				DWORD dwActiveProtocol;

				READ_BODY(rcStr)

				if (MSGCheckHandleAssociation(rcStr.hCard, threadContext))
					goto exit;

				rcStr.rv = SCardReconnect(rcStr.hCard, rcStr.dwShareMode,
					rcStr.dwPreferredProtocols, rcStr.dwInitialization,
					&dwActiveProtocol);
				rcStr.dwActiveProtocol = dwActiveProtocol;

				WRITE_BODY(rcStr)
			}
			break;

			case SCARD_DISCONNECT:
			{
				struct disconnect_struct diStr;

				READ_BODY(diStr)

				if (MSGCheckHandleAssociation(diStr.hCard, threadContext))
					goto exit;

				diStr.rv = SCardDisconnect(diStr.hCard, diStr.dwDisposition);

				if (SCARD_S_SUCCESS == diStr.rv)
					diStr.rv = MSGRemoveHandle(diStr.hCard, threadContext);

				WRITE_BODY(diStr)
			}
			break;

			case SCARD_BEGIN_TRANSACTION:
			{
				struct begin_struct beStr;

				READ_BODY(beStr)

				if (MSGCheckHandleAssociation(beStr.hCard, threadContext))
					goto exit;

				beStr.rv = SCardBeginTransaction(beStr.hCard);

				WRITE_BODY(beStr)
			}
			break;

			case SCARD_END_TRANSACTION:
			{
				struct end_struct enStr;

				READ_BODY(enStr)

				if (MSGCheckHandleAssociation(enStr.hCard, threadContext))
					goto exit;

				enStr.rv = SCardEndTransaction(enStr.hCard,
					enStr.dwDisposition);

				WRITE_BODY(enStr)
			}
			break;

			case SCARD_CANCEL:
			{
				struct cancel_struct caStr;
				SCONTEXT * psTargetContext = NULL;
				READ_BODY(caStr)

				/* find the client */
				(void)pthread_mutex_lock(&contextsList_lock);
				psTargetContext = (SCONTEXT *) list_seek(&contextsList,
					&caStr.hContext);
				(void)pthread_mutex_unlock(&contextsList_lock);
				if (psTargetContext != NULL)
				{
					uint32_t fd = psTargetContext->dwClientID;
					caStr.rv = MSGSignalClient(fd, SCARD_E_CANCELLED);
				}
				else
					caStr.rv = SCARD_E_INVALID_HANDLE;

				WRITE_BODY(caStr)
			}
			break;

			case SCARD_STATUS:
			{
				struct status_struct stStr;

				READ_BODY(stStr)

				if (MSGCheckHandleAssociation(stStr.hCard, threadContext))
					goto exit;

				/* only hCard and return value are used by the client */
				stStr.rv = SCardStatus(stStr.hCard, NULL, NULL, NULL,
					NULL, 0, NULL);

				WRITE_BODY(stStr)
			}
			break;

			case SCARD_TRANSMIT:
			{
				struct transmit_struct trStr;
				unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
				unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
				SCARD_IO_REQUEST ioSendPci;
				SCARD_IO_REQUEST ioRecvPci;
				DWORD cbRecvLength;

				READ_BODY(trStr)

				if (MSGCheckHandleAssociation(trStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if ((trStr.pcbRecvLength > sizeof(pbRecvBuffer))
					|| (trStr.cbSendLength > sizeof(pbSendBuffer)))
					goto buffer_overflow;

				/* read sent buffer */
				ret = MessageReceive(pbSendBuffer, trStr.cbSendLength, filedes);
				if (ret != SCARD_S_SUCCESS)
				{
					Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
					goto exit;
				}

				ioSendPci.dwProtocol = trStr.ioSendPciProtocol;
				ioSendPci.cbPciLength = trStr.ioSendPciLength;
				ioRecvPci.dwProtocol = trStr.ioRecvPciProtocol;
				ioRecvPci.cbPciLength = trStr.ioRecvPciLength;
				cbRecvLength = trStr.pcbRecvLength;

				trStr.rv = SCardTransmit(trStr.hCard, &ioSendPci,
					pbSendBuffer, trStr.cbSendLength, &ioRecvPci,
					pbRecvBuffer, &cbRecvLength);

				trStr.ioSendPciProtocol = ioSendPci.dwProtocol;
				trStr.ioSendPciLength = ioSendPci.cbPciLength;
				trStr.ioRecvPciProtocol = ioRecvPci.dwProtocol;
				trStr.ioRecvPciLength = ioRecvPci.cbPciLength;
				trStr.pcbRecvLength = cbRecvLength;

				WRITE_BODY(trStr)

				/* write received buffer */
				if (SCARD_S_SUCCESS == trStr.rv)
					ret = MessageSend(pbRecvBuffer, cbRecvLength, filedes);
			}
			break;

			case SCARD_CONTROL:
			{
				struct control_struct ctStr;
				unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
				unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
				DWORD dwBytesReturned;

				READ_BODY(ctStr)

				if (MSGCheckHandleAssociation(ctStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if ((ctStr.cbRecvLength > sizeof(pbRecvBuffer))
					|| (ctStr.cbSendLength > sizeof(pbSendBuffer)))
				{
					goto buffer_overflow;
				}

				/* read sent buffer */
				ret = MessageReceive(pbSendBuffer, ctStr.cbSendLength, filedes);
				if (ret != SCARD_S_SUCCESS)
				{
					Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
					goto exit;
				}

				dwBytesReturned = ctStr.dwBytesReturned;

				ctStr.rv = SCardControl(ctStr.hCard, ctStr.dwControlCode,
					pbSendBuffer, ctStr.cbSendLength,
					pbRecvBuffer, ctStr.cbRecvLength,
					&dwBytesReturned);

				ctStr.dwBytesReturned = dwBytesReturned;

				WRITE_BODY(ctStr)

				/* write received buffer */
				if (SCARD_S_SUCCESS == ctStr.rv)
					ret = MessageSend(pbRecvBuffer, dwBytesReturned, filedes);
			}
			break;

			case SCARD_GET_ATTRIB:
			{
				struct getset_struct gsStr;
				DWORD cbAttrLen;

				READ_BODY(gsStr)

				if (MSGCheckHandleAssociation(gsStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if (gsStr.cbAttrLen > sizeof(gsStr.pbAttr))
					goto buffer_overflow;

				cbAttrLen = gsStr.cbAttrLen;

				gsStr.rv = SCardGetAttrib(gsStr.hCard, gsStr.dwAttrId,
					gsStr.pbAttr, &cbAttrLen);

				gsStr.cbAttrLen = cbAttrLen;

				WRITE_BODY(gsStr)
			}
			break;

			case SCARD_SET_ATTRIB:
			{
				struct getset_struct gsStr;

				READ_BODY(gsStr)

				if (MSGCheckHandleAssociation(gsStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if (gsStr.cbAttrLen > sizeof(gsStr.pbAttr))
					goto buffer_overflow;

				gsStr.rv = SCardSetAttrib(gsStr.hCard, gsStr.dwAttrId,
					gsStr.pbAttr, gsStr.cbAttrLen);

				WRITE_BODY(gsStr)
			}
			break;

			default:
				Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", header.command);
				goto exit;
		}

		/* MessageSend() failed */
		if (ret != SCARD_S_SUCCESS)
		{
			/* Clean up the dead client */
			Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
			goto exit;
		}
	}

buffer_overflow:
	Log2(PCSC_LOG_DEBUG, "Buffer overflow detected: %d", filedes);
	goto exit;
wrong_length:
	Log2(PCSC_LOG_DEBUG, "Wrong length: %d", filedes);
exit:
	(void)close(filedes);
	(void)MSGCleanupClient(threadContext);
	(void)pthread_exit((LPVOID) NULL);
}
Example #7
0
///=================================================================================
// creates the binary circuit that consits of only gate infomation
// input: the number of items of each server,	
//        the number of servers,
//        the number of bits for each item "value" (for multiparty computation)
// output: void
BOOL CP2PCircuit::Create(int nParties, const vector<int>& vParams)
{
	int num_servers = nParties - 1;
	
	int num_items  = vParams[0];
	int input_range = vParams[1];

	if( vParams.size() < 2 )
	{
		cout << "Error! This circuit needs two parameters: #items and input_range." << endl;
		return FALSE;
	}

	int tot_items;		// # of items of all servers
	int num_vbits;		// # of bits to represent each value	
	int num_bits;		// # of bits to identify [0, num_items]
	int num_gates;		// # of gates required to create the circuit
	int num_layers;		// # of layers for the tournament
	int num_andgates;	// # of AND gates
	int num_mux_val;	// # of MUX circuit for values
	int num_mux_idx;	// # of MUX circuit for indexes
	int num_cmp;		// # of comparison (circuit)
	int num_in;			// # of IN gates
	int num_out;		// # of OUT gates
	int num_vs_bottom;	// # of gates for each vs at the bottom of tournament 
	int num_vs_middle;	// # of gates for each vs between the bottom and top of the tournament
	int num_vs_top;		// # of gates for each vs at top of the tournament
	//vector<int> outputs = vector<int>();	// final outputs that will be given to OUT gates
	
	tot_items = num_items * num_servers;

	// collects necessary info first
	num_bits = GetNumBits(tot_items);
	num_vbits = input_range >= 0? GetNumBits(input_range) : num_bits;
	//num_vbits = -1;
	
	num_layers = (int)ceil(Log2(tot_items));
	//num_andgates = tot_items * num_bits;
	num_andgates = tot_items * num_vbits;
	num_cmp = tot_items - 1;
	num_mux_val = num_cmp - 1;
	num_mux_idx = num_cmp;
	//num_in = 2+ tot_items*num_bits + tot_items;
	num_in = 2+ tot_items*num_vbits + tot_items;
	num_out = num_bits;
	//num_gates = num_andgates + (num_mux_val+num_mux_idx)*MUX_GATES*num_bits 
	//	+ num_cmp*CMP_GATES*num_bits + num_in +num_out;
	num_gates = num_andgates + num_mux_val*MUX_GATES*num_vbits
		+ num_mux_idx*MUX_GATES*num_bits + num_cmp*CMP_GATES*num_vbits + num_in +num_out;
	//num_gates = GetNumGates(tot_items, num_bits);

	//num_vs_bottom = num_bits*2 + CMP_GATES*num_bits + 2*MUX_GATES*num_bits;
	num_vs_bottom = num_vbits*2 + CMP_GATES*num_vbits + MUX_GATES*(num_bits+num_vbits);
	//num_vs_middle = num_vs_bottom - 2*num_bits;
	num_vs_middle = num_vs_bottom - 2*num_vbits;
	num_vs_top = num_vs_middle - MUX_GATES*num_bits;
	num_vs_top = num_vs_middle - MUX_GATES*num_vbits;

	// circuit initialization
	cout << " Total # of gates:" << num_gates << endl;
	cout << " Total # of gates for bottom vs:" << num_vs_bottom << endl;
	cout << " Total # of gates for middle vs:" << num_vs_middle << endl;
	cout << " Total # of gates for top vs:" << num_vs_top << endl;
	cout << " Total # of IN gates:" << num_in << endl;

	m_nNumGates = num_gates;
	//m_nNumBits = num_bits;
	m_nNumItems = num_items; 
	//m_nNumVBits = input_range >= 0 ? GetNumBits(input_range) : num_bits;
	m_nNumServers = num_servers;
	m_nNumXORs = 0;
	m_vNumVBits.resize(nParties,num_vbits);
	m_vNumVBits[nParties-1] = 1;

	m_pGates = new GATE[num_gates];  
	if (m_pGates == NULL){
		puts("CP2PCircuit::Create(const int): memory error");
		exit(-1);
	}
	for (int i=0;i<num_gates;i++){
		(m_pGates+i)->left = -1;
		(m_pGates+i)->right = -1;
		(m_pGates+i)->p_num = 0;
	}
	 

	// starts creating the circuit	
	int id = 0;				// gate id
	int is_left = 1;		// left - 1, right - 0	
	int is_final = 0;		// final comparison: yes - 1, no - 0
	int is_bottompair = 0;	// indicates whether the comparison is a pair at the bottom of tournament
	int is_bottomsingle = 0;// indicates whether the comparison is a single at the bottom of tournament
	int is_middle = 0;		// indicates whether the comparison is in the middle of tournament
	int is_alone = 0;		// whether the vs is a pair or single
	int is_moreMUXvalue = 0;// whether the higher layer's vs uses MUX_value
	int num_remainders;		// # of items that remain on the tournament
	int gates_skip;			// # of gates that should be skipped
	int layer_no=0;			// layer number from the bottom of the tournament starting from 0
	int* vs_no;				// # of completed vs from the leftmost (on the current layer) of the tournament starting from 0
	int* layer_waiting;	// # of waitings at each layer
	int* is_left_before;	// whether last vs was left or right
	
	num_remainders = tot_items;
	
	layer_waiting = new int[num_layers+1];
	vs_no = new int[num_layers+1];
	is_left_before = new int[num_layers+1];
	for (int i=0;i<num_layers;i++){
		layer_waiting[i] = 0;
		vs_no[i]=0;
		is_left_before[i] = -1;
	}

	// IN gates for const inputs 0 and 1
	(m_pGates+id)->type = G_XOR;
	(m_pGates+id)->right = 0;
	id++;
	(m_pGates+id)->type = G_XOR;
	(m_pGates+id)->right = 0;
	id++;
	
	// creates gates for server inputs
	int tmp_num_bits;
	if (num_vbits <= 0){
		tmp_num_bits = num_bits;	// for two party computation
	}
	else{
		tmp_num_bits = num_vbits;	// for multiparty computation
	}
	m_serStartGate = id;
	for (int i=0;i<num_servers;i++){
		m_vInputStart.push_back(id);
		for (int j=0;j<num_items;j++){
			for (int k=0;k<tmp_num_bits;k++,id++){
				(m_pGates+id)->type = G_XOR;
				(m_pGates+id)->right = 0;
			}
		}
		m_vInputEnd.push_back(id-1);
	}
	
	// creates gates for client inputs
	m_cliStartGate = id;
	m_vInputStart.push_back(id);
	for(int i=0;i<tot_items;i++,id++){
		(m_pGates+id)->type = G_XOR;
		(m_pGates+id)->right = 0;
	}
	m_vInputEnd.push_back(id-1);

	// creates gates for output of each party
	// servers
	for (int i=0;i<nParties-1;i++){
		// no output for servers
		m_vOutputStart.push_back(0);
		m_vOutputEnd.push_back(-1);
	}

	// output for client
	m_vOutputStart.push_back(num_gates-num_out);
	m_vOutputEnd.push_back(num_gates-1);
	for(int i=0;i<num_out;i++){
		(m_pGates+m_vOutputStart[num_servers]+i)->type = G_XOR;
		(m_pGates+m_vOutputStart[num_servers]+i)->p_num = 0;
		(m_pGates+m_vOutputStart[num_servers]+i)->right = 0;
	}

	// creates gates other than server and client's input gates
	m_othStartGate = id;
	for (int i=0;i<num_cmp;i++){
		if (i== num_cmp-1){
			is_final = 1;	
		}

		int tmp=0;
		int layer_no_tmp=-1;
		// compares with two same layers (bottom layer not included)
		assert(layer_no >= 0);
		if (layer_waiting[layer_no] == 2){
			is_alone = 0;
			//is_left = 1;///////////////////////////////
			if (is_left_before[layer_no] == 1){
				is_left = 0;
				is_left_before[layer_no] = is_left;
			}
			else if (is_left_before[layer_no] == -1){
				is_left = 1;
				is_left_before[layer_no] = is_left;
			}
			else if (is_left_before[layer_no] == 0){
				is_left = IsVSLeft(tot_items,layer_no, vs_no);
				//tmp = tot_items - 2*vs_no[layer_no];
				is_left_before[layer_no] = is_left;
			}
			
			if (is_left){
				if (layer_no >= num_layers-2){
					is_moreMUXvalue = 0;
				}
				else{
					is_moreMUXvalue = 1;
				}
			}
			else {// && num_remainders>0){
				is_moreMUXvalue = 0;
				for (int j=layer_no+1;j<num_layers-1;j++){

					#ifdef _DEBUG
					assert(j >= 0);
					#endif
					
					if (layer_waiting[j] == 1){
						is_moreMUXvalue = 1;
						break;
					}
				}
			}
			
			if (is_left){
				gates_skip = GetGatesSkip(tot_items, num_vbits, layer_no, num_vs_bottom, num_vs_middle, vs_no);
			}

			id = CreateCMP(id, is_final, num_bits, num_vbits);
			if (!is_final){
				id = CreateMUXValue(id, is_final, num_bits, num_vbits,is_left, gates_skip,is_moreMUXvalue);
			}
			id = CreateMUXIndex(id, is_final, num_bits, num_vbits, is_left, layer_no, gates_skip,is_moreMUXvalue, vs_no, is_alone, nParties);
			
			vs_no[layer_no]++;
			layer_waiting[layer_no]=0;
			
			#ifdef _DEBUG
			assert( layer_no >= 0);
			#endif
			
			layer_no++;
			layer_waiting[layer_no]++;

			#ifdef _DEBUG
			assert( layer_no <= num_layers);
			#endif
			
		}
		// compares with different layers (bottom layer not included)
		else if (num_remainders == 0){
			is_alone= 0;
			is_left = 0;

			for (int j=layer_no+1;j<num_layers;j++){

				#ifdef _DEBUG
				assert( j >= 0 );
				#endif
			
				if (layer_waiting[j] == 1){
					layer_waiting[j] = 0;
					vs_no[j]++;
					layer_no_tmp = j+1;
					break;
				}
			}
			if (layer_no_tmp == -1){
				puts("CP2PCircuit::Create(const int): layer_no_tmp is -1");		
				exit(-1);
			}

			//if (layer_no_tmp == num_layers-1){	// higher layer (one above) is the top layer
			//	is_moreMUXvalue=0;
			//}
			//else{
			//	is_moreMUXvalue=1;
			//}
			
			is_moreMUXvalue = 0;
			for (int j=layer_no_tmp;j<num_layers-1;j++){

				#ifdef _DEBUG
				assert( j >= 0 );
				#endif
		

				if (layer_waiting[j] == 1){
					is_moreMUXvalue = 1;
					break;
				}
			}

			id = CreateCMP(id, is_final, num_bits, num_vbits);
			if (!is_final){
				id = CreateMUXValue(id, is_final, num_bits, num_vbits,is_left, gates_skip,is_moreMUXvalue);
			}
			id = CreateMUXIndex(id, is_final, num_bits, num_vbits, is_left, layer_no, gates_skip,is_moreMUXvalue, vs_no, is_alone, nParties);
			
			layer_waiting[layer_no]=0;

			#ifdef _DEBUG
			assert( layer_no >= 0 && layer_no < num_layers);
			#endif
		

			layer_no = layer_no_tmp;
			layer_waiting[layer_no]++;

			//#ifdef _DEBUG
			//assert( layer_no >= 0 && layer_no < num_layers);
			//#endif
		
		}
		// compares with different layers (only one layer is bottom)
		else if (num_remainders == 1){
			layer_no = 0;
			is_alone = 1;
			is_left = 0;
			
			for (int j=layer_no+1;j<num_layers;j++){

				#ifdef _DEBUG
				assert( j >= 0 );  
				#endif
		
				if (layer_waiting[j] == 1){
					layer_waiting[j] = 0;
					vs_no[j]++;
					layer_no_tmp = j+1;
					break;
				}
			}
			if (layer_no_tmp == -1){
				puts("CP2PCircuit::Create(const int): layer_no_tmp is -1");		
				exit(-1);
			}
			/*
			if (layer_no_tmp == num_layers){	// higher layer (one above) is the top layer
				is_moreMUXvalue=0;
			}
			else{
				is_moreMUXvalue=1;
			}
			*/
			is_moreMUXvalue = 0;
			for (int j=layer_no_tmp;j<num_layers-1;j++){

				#ifdef _DEBUG
				assert( j >= 0 );  
				#endif
		
				if (layer_waiting[j] == 1){
					is_moreMUXvalue = 1;
					break;
				}
			}
			
			id = CreateANDRight(id, is_final, num_vbits, vs_no, 1);
			id = CreateCMP(id, is_final, num_bits, num_vbits);
			if (!is_final){
				id = CreateMUXValue(id, is_final, num_bits, num_vbits, is_left, gates_skip,is_moreMUXvalue);
			}
			id = CreateMUXIndex(id, is_final, num_bits, num_vbits, is_left, layer_no, gates_skip,is_moreMUXvalue, vs_no, is_alone, nParties);

			layer_no = layer_no_tmp;
			layer_waiting[layer_no]++;
			num_remainders--;

			#ifdef _DEBUG
			assert( layer_no >= 0 && layer_no < num_layers);
			#endif
		
		}
		// compares with two bottom layers
		else if (num_remainders >= 2){
			layer_no = 0;
			is_alone = 0;
			if (is_left_before[layer_no] == 1){
				is_left = 0;
				is_left_before[layer_no] = is_left;
			}
			else if (is_left_before[layer_no] == -1){
				is_left = 1;
				is_left_before[layer_no] = is_left;
			}
			else if (is_left_before[layer_no] == 0){
				is_left = IsVSLeft(tot_items,layer_no, vs_no);
				//tmp = tot_items - 2*vs_no[layer_no];
				is_left_before[layer_no] = is_left;
			}
			
			if (num_layers<=2){
				is_moreMUXvalue = 0;
			}
			else if(is_left){
				is_moreMUXvalue = 1;
			}
			else {
				is_moreMUXvalue = 0;
				for (int j=layer_no+1;j<num_layers-1;j++){

					#ifdef _DEBUG
					assert( j >= 0 );
					#endif
		
					if (layer_waiting[j] == 1){
						is_moreMUXvalue = 1;
						break;
					}
				}
			}
			if (is_left){						
				gates_skip = GetGatesSkip(tot_items, num_vbits, layer_no, num_vs_bottom, num_vs_middle, vs_no);
			}
			//id = CreateInputLeft(id, is_final, num_bits);
			//id = CreateInputRight(id, is_final, num_bits);
			id = CreateANDLeft(id, is_final, num_vbits, vs_no);
			id = CreateANDRight(id, is_final, num_vbits, vs_no, 0);
			id = CreateCMP(id, is_final, num_bits, num_vbits);
			if (!is_final){
				id = CreateMUXValue(id, is_final, num_bits, num_vbits, is_left, gates_skip, is_moreMUXvalue);
			}
			id = CreateMUXIndex(id, is_final, num_bits, num_vbits, is_left, layer_no, gates_skip,is_moreMUXvalue, vs_no, is_alone, nParties);
			
			vs_no[layer_no]++;
			layer_no = 1;
			layer_waiting[layer_no]++;
			num_remainders -= 2;

			#ifdef _DEBUG
			assert( layer_no >= 0 && layer_no < num_layers);
			#endif
		
		}
	}

	#ifdef _DEBUG
	cout << "final gate id: " << id-1+num_out << endl;
	#endif

	delete [] layer_waiting;
	delete [] vs_no;
	delete [] is_left_before; 

	m_nNumParties = m_nNumServers + 1;
	m_vInputStart.resize(m_nNumParties);
	m_vInputEnd.resize(m_nNumParties);

	//for(int i=0; i<m_nNumParties; i++)
	//{
	//	m_vInputStart[i] = GetInputStartC(i);
	//	m_vInputEnd[i] = GetInputEndC(i);
	//}

	#ifdef _DEBUG
	cout << "input start gate id1: " << m_vInputStart[0] << endl;
	cout << "input end gate id1: " << m_vInputEnd[0] << endl;
	cout << "input start gate id2: " << m_vInputStart[1] << endl;
	cout << "input end gate id2: " << m_vInputEnd[1] << endl;
	cout << "input start gate id3: " << m_vInputStart[2] << endl;
	cout << "input end gate id3: " << m_vInputEnd[2] << endl;
	cout << "output start gate id1: " << m_vOutputStart[0] << endl;
	cout << "output end gate id1: " << m_vOutputEnd[0] << endl;
	cout << "output start gate id2: " << m_vOutputStart[1] << endl;
	cout << "output end gate id2: " << m_vOutputEnd[1] << endl;
	cout << "output start gate id3: " << m_vOutputStart[2] << endl;
	cout << "output end gate id3: " << m_vOutputEnd[2] << endl;
	#endif

	return TRUE;
}
Example #8
0
void bspParSort(){

  int Log2(int x);
  void mergeSort(int x, int *temp1);
  void merge2(int *arr1, int *arr2, int size);

  int *localArr; /* local array in each processor */
  int i,j,k; /* index variables */
  int n_divide_p; /* Avoid multiple computation */
  int n; /* Number of elements to be sorted */
  int szLocalArray; /* Size of local array */
  double time0, time1; /* Time */
  FILE *ifp = 0; /* Reader to read sequence of numbers to be sorted */

  bsp_begin(P);
  int p= bsp_nprocs(); /* Number of processors obtained */ 
  int s= bsp_pid();    /* Processor number */ 

  //Get number of elements to be sorted
  if(s==0){
    ifp = fopen("sort","r");
    if(ifp == NULL){
      fprintf(stderr, "Can't open input file!\n");
      exit(1);
    }
    fscanf(ifp, "%i", &n);
  }

  // Make sure every processor knows everything
  bsp_push_reg(&n,sizeof(int));
  bsp_sync();
  bsp_get(0,&n,0,&n,sizeof(int));
  bsp_sync();
  bsp_pop_reg(&n);

  //Setup distribution 
  n_divide_p = n/p;
  szLocalArray = n/pow(2,ceil(Log2(s+1)));
  localArr = vecalloci(szLocalArray);
  bsp_push_reg(localArr,sizeof(int)*szLocalArray);

  if(s==0){ 
    printf("Distribution start\n"); fflush(stdout); 
  }

  bsp_sync();
  int value;
  if(s==0){
    //allocate to array on proc 0
    for(i=0; i< n_divide_p; i++){
      fscanf(ifp, "%i", &value);
      localArr[i]=value;      
    }
    //Send to arrays on other processors
    for(i=1; i< p; i++){
      for(j=0;j<n_divide_p;j++){
        fscanf(ifp, "%i", &value);
        bsp_put(i,&value,localArr,j*sizeof(int),sizeof(int));
      }
    }
    fclose(ifp);
  }
  bsp_sync();
  if(s==0){ 
    printf("Distribution done\n"); fflush(stdout); 
  }

  //Distribution done and we can start time measurement 
  if(s==0){
    printf("Time start\n"); fflush(stdout);
  }
  time0 = bsp_time();

  //Locally sort each array
  if(s==0){
    printf("Local sort\n"); fflush(stdout);
  }
  mergeSort(n_divide_p, localArr);
  bsp_sync();

  //Merging 
  int *temp = malloc(sizeof(int)*pow(2,Log2(p))*n_divide_p);
  for(j=1;j<Log2(p)+1;j++){
    if(s<p/pow(2,j)){
      for(k=0;k<pow(2,j-1)*n_divide_p;k++){
        bsp_get(s+(p/pow(2,j)),localArr,k*sizeof(int),&(temp[k]),sizeof(int));
      }
    }
    bsp_sync();

    if(s<p/pow(2,j)){
      merge2(localArr, temp, n_divide_p*pow(2,j-1));
    }

    bsp_sync();
    if(s==0){ 
      printf("Round %i out of %i rounds of merging done (on proc 0)\n",j,Log2(p)); fflush(stdout); 
    }
  }
  if(s==0){
    printf("Sorting done\n"); fflush(stdout);
  }
  bsp_sync();
 
  //Print sorted array - expensive if sample is big
  /*
  if(s==0){
    printf("Sorted sequence is:\n");
    for(i=0; i<szLocalArray; i++){
      printf("%i ",localArr[i]); fflush(stdout);
    }
    printf("\n"); fflush(stdout);
  }
  */

  //Parallel algorithm ends
  time1 = bsp_time();
  if(s==0){
    printf("Time stop\n"); fflush(stdout);
  }

  //Report time to user
  if(s==0){
    printf("Sorting took %.6lf seconds.\n", time1-time0); fflush(stdout);
  }
  
  //Clean up
  free(temp);
  bsp_pop_reg(localArr); free(localArr);

  bsp_end();
} /* End bspParSort */
Example #9
0
/*
**************************************************************************
*
*  Function    : dtx_dec
*                
**************************************************************************
*/
int dtx_dec(
   dtx_decState *st,                /* i/o : State struct                    */
   Word16 mem_syn[],                /* i/o : AMR decoder state               */
   D_plsfState* lsfState,           /* i/o : decoder lsf states              */
   gc_predState* predState,         /* i/o : prediction states               */
   Cb_gain_averageState* averState, /* i/o : CB gain average states          */
   enum DTXStateType new_state,     /* i   : new DTX state                   */
   enum Mode mode,                  /* i   : AMR mode                        */
   Word16 parm[],                   /* i   : Vector of synthesis parameters  */
   Word16 synth[],                  /* o   : synthesised speech              */
   Word16 A_t[]                     /* o   : decoded LP filter in 4 subframes*/
   )
{
   Word16 log_en_index;
   Word16 i, j;
   Word16 int_fac;
   Word32 L_log_en_int;
   Word16 lsp_int[M];
   Word16 log_en_int_e;
   Word16 log_en_int_m;
   Word16 level;
   Word16 acoeff[M + 1];
   Word16 refl[M];
   Word16 pred_err;
   Word16 ex[L_SUBFR];
   Word16 ma_pred_init;
   Word16 log_pg_e, log_pg_m;
   Word16 log_pg;
   Flag negative;
   Word16 lsf_mean;
   Word32 L_lsf_mean;
   Word16 lsf_variab_index;
   Word16 lsf_variab_factor;
   Word16 lsf_int[M];
   Word16 lsf_int_variab[M];
   Word16 lsp_int_variab[M];
   Word16 acoeff_variab[M + 1];

   Word16 lsf[M];
   Word32 L_lsf[M];
   Word16 ptr;
   Word16 tmp_int_length;


   /*  This function is called if synthesis state is not SPEECH 
    *  the globally passed  inputs to this function are 
    * st->sid_frame 
    * st->valid_data 
    * st->dtxHangoverAdded
    * new_state  (SPEECH, DTX, DTX_MUTE)
    */

   test(); test();
   if ((st->dtxHangoverAdded != 0) && 
       (st->sid_frame != 0))
   {
      /* sid_first after dtx hangover period */
      /* or sid_upd after dtxhangover        */

      /* set log_en_adjust to correct value */
      st->log_en_adjust = dtx_log_en_adjust[mode];
          
      ptr = add(st->lsf_hist_ptr, M);                               move16(); 
      test();
      if (sub(ptr, 80) == 0)
      {
         ptr = 0;                                                   move16();
      }
      Copy( &st->lsf_hist[st->lsf_hist_ptr],&st->lsf_hist[ptr],M); 
      
      ptr = add(st->log_en_hist_ptr,1);                             move16();
      test();
      if (sub(ptr, DTX_HIST_SIZE) == 0)
      {
         ptr = 0;                                                   move16();
      }
      move16();
      st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; /* Q11 */
      
      /* compute mean log energy and lsp *
       * from decoded signal (SID_FIRST) */         
      st->log_en = 0;                                               move16();
      for (i = 0; i < M; i++)
      {
         L_lsf[i] = 0;                                              move16();
      }
      
      /* average energy and lsp */
      for (i = 0; i < DTX_HIST_SIZE; i++)
      {
         st->log_en = add(st->log_en,
                          shr(st->log_en_hist[i],3));
         for (j = 0; j < M; j++)
         {
            L_lsf[j] = L_add(L_lsf[j],
                             L_deposit_l(st->lsf_hist[i * M + j]));
         }
      }
       
      for (j = 0; j < M; j++)
      {
         lsf[j] = extract_l(L_shr(L_lsf[j],3)); /* divide by 8 */  move16();
      }
      
      Lsf_lsp(lsf, st->lsp, M); 

      /* make log_en speech coder mode independent */
      /* added again later before synthesis        */
      st->log_en = sub(st->log_en, st->log_en_adjust);

      /* compute lsf variability vector */
      Copy(st->lsf_hist, st->lsf_hist_mean, 80);

      for (i = 0; i < M; i++)
      {
         L_lsf_mean = 0;                                           move32();
         /* compute mean lsf */
         for (j = 0; j < 8; j++)
         {
            L_lsf_mean = L_add(L_lsf_mean, 
                               L_deposit_l(st->lsf_hist_mean[i+j*M]));
         }
         
         lsf_mean = extract_l(L_shr(L_lsf_mean, 3));               move16();
         /* subtract mean and limit to within reasonable limits  *
          * moreover the upper lsf's are attenuated              */
         for (j = 0; j < 8; j++)
         {
            /* subtract mean */ 
            st->lsf_hist_mean[i+j*M] = 
               sub(st->lsf_hist_mean[i+j*M], lsf_mean);

            /* attenuate deviation from mean, especially for upper lsf's */
            st->lsf_hist_mean[i+j*M] = 
               mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i]);

            /* limit the deviation */
            test();
            if (st->lsf_hist_mean[i+j*M] < 0)
            {
               negative = 1;                                        move16();
            }
            else
            {
               negative = 0;                                        move16();
            }
            st->lsf_hist_mean[i+j*M] = abs_s(st->lsf_hist_mean[i+j*M]);

            /* apply soft limit */
            test();
            if (sub(st->lsf_hist_mean[i+j*M], 655) > 0)
            {
               st->lsf_hist_mean[i+j*M] = 
                  add(655, shr(sub(st->lsf_hist_mean[i+j*M], 655), 2));
            }
            
            /* apply hard limit */
            test();
            if (sub(st->lsf_hist_mean[i+j*M], 1310) > 0)
            {
               st->lsf_hist_mean[i+j*M] = 1310;                     move16();
            }
            test();
            if (negative != 0) 
            {
               st->lsf_hist_mean[i+j*M] = -st->lsf_hist_mean[i+j*M];move16();
            }
            
         }
      }
   }
   
   test();
   if (st->sid_frame != 0 )
   {
      /* Set old SID parameters, always shift */
      /* even if there is no new valid_data   */
      Copy(st->lsp, st->lsp_old, M);
      st->old_log_en = st->log_en;                                  move16();

      test();
      if (st->valid_data != 0 )  /* new data available (no CRC) */
      {
         /* Compute interpolation factor, since the division only works *
          * for values of since_last_sid < 32 we have to limit the      *
          * interpolation to 32 frames                                  */
         tmp_int_length = st->since_last_sid;                       move16();
         st->since_last_sid = 0;                                    move16();

         test();
         if (sub(tmp_int_length, 32) > 0)
         {
            tmp_int_length = 32;                                    move16();
         }
         test();
         if (sub(tmp_int_length, 2) >= 0)
         {
            move16();
            st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); 
         }
         else
         {
            st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */     move16();
         }
         
         Init_D_plsf_3(lsfState, parm[0]);  /* temporay initialization */ 
         D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp);
         Set_zero(lsfState->past_r_q, M);   /* reset for next speech frame */ 

         log_en_index = parm[4];                                    move16();
         /* Q11 and divide by 4 */
         st->log_en = shl(log_en_index, (11 - 2));                  move16();
         
         /* Subtract 2.5 in Q11 */
         st->log_en = sub(st->log_en, (2560 * 2));
         
         /* Index 0 is reserved for silence */
         test();
         if (log_en_index == 0)
         {
            st->log_en = MIN_16;                                    move16();
         }
         
         /* no interpolation at startup after coder reset        */
         /* or when SID_UPD has been received right after SPEECH */
         test(); test();
         if ((st->data_updated == 0) ||
             (sub(st->dtxGlobalState, SPEECH) == 0)
             ) 
         {
            Copy(st->lsp, st->lsp_old, M);
            st->old_log_en = st->log_en;                            move16();
         }         
      } /* endif valid_data */

      /* initialize gain predictor memory of other modes */       
      ma_pred_init = sub(shr(st->log_en,1), 9000);                  move16();
      test();
      if (ma_pred_init > 0)
      {                   
         ma_pred_init = 0;                                          move16();  
      }      
      test();
      if (sub(ma_pred_init, -14436) < 0)
      {
         ma_pred_init = -14436;                                     move16();
      }
      
      predState->past_qua_en[0] = ma_pred_init;                     move16();
      predState->past_qua_en[1] = ma_pred_init;                     move16();
      predState->past_qua_en[2] = ma_pred_init;                     move16();
      predState->past_qua_en[3] = ma_pred_init;                     move16();

      /* past_qua_en for other modes than MR122 */      
      ma_pred_init = mult(5443, ma_pred_init); 
      /* scale down by factor 20*log10(2) in Q15 */
      predState->past_qua_en_MR122[0] = ma_pred_init;               move16();
      predState->past_qua_en_MR122[1] = ma_pred_init;               move16();
      predState->past_qua_en_MR122[2] = ma_pred_init;               move16();
      predState->past_qua_en_MR122[3] = ma_pred_init;               move16();
   } /* endif sid_frame */
   
   /* CN generation */
   /* recompute level adjustment factor Q11             *
    * st->log_en_adjust = 0.9*st->log_en_adjust +       *
    *                     0.1*dtx_log_en_adjust[mode]); */
   move16();
   st->log_en_adjust = add(mult(st->log_en_adjust, 29491),
                           shr(mult(shl(dtx_log_en_adjust[mode],5),3277),5));

   /* Interpolate SID info */
   int_fac = shl(add(1,st->since_last_sid), 10); /* Q10 */                 move16();
   int_fac = mult(int_fac, st->true_sid_period_inv); /* Q10 * Q15 -> Q10 */
   
   /* Maximize to 1.0 in Q10 */
   test();
   if (sub(int_fac, 1024) > 0)
   {
      int_fac = 1024;                                               move16();
   }
   int_fac = shl(int_fac, 4); /* Q10 -> Q14 */
   
   L_log_en_int = L_mult(int_fac, st->log_en); /* Q14 * Q11->Q26 */ move32();
   for(i = 0; i < M; i++)
   {
      lsp_int[i] = mult(int_fac, st->lsp[i]);/* Q14 * Q15 -> Q14 */ move16();
   }
   
   int_fac = sub(16384, int_fac); /* 1-k in Q14 */                  move16();

   /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */
   L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en);
   for(i = 0; i < M; i++)
   {
      /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
      lsp_int[i] = add(lsp_int[i], mult(int_fac, st->lsp_old[i]));  move16();
      lsp_int[i] = shl(lsp_int[i], 1); /* Q14 -> Q15 */             move16();
   }
   
   /* compute the amount of lsf variability */
   lsf_variab_factor = sub(st->log_pg_mean,2457); /* -0.6 in Q12 */ move16();
   /* *0.3 Q12*Q15 -> Q12 */
   lsf_variab_factor = sub(4096, mult(lsf_variab_factor, 9830)); 

   /* limit to values between 0..1 in Q12 */ 
   test();
   if (sub(lsf_variab_factor, 4096) > 0)
   {
      lsf_variab_factor = 4096;                                     move16();
   }
   test();
   if (lsf_variab_factor < 0)
   {
      lsf_variab_factor = 0;                                        move16(); 
   }
   lsf_variab_factor = shl(lsf_variab_factor, 3); /* -> Q15 */      move16();

   /* get index of vector to do variability with */
   lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3);            move16();

   /* convert to lsf */
   Lsp_lsf(lsp_int, lsf_int, M);

   /* apply lsf variability */
   Copy(lsf_int, lsf_int_variab, M);
   for(i = 0; i < M; i++)
   {
      move16();
      lsf_int_variab[i] = add(lsf_int_variab[i], 
                              mult(lsf_variab_factor,
                                   st->lsf_hist_mean[i+lsf_variab_index*M]));
   }

   /* make sure that LSP's are ordered */
   Reorder_lsf(lsf_int, LSF_GAP, M);
   Reorder_lsf(lsf_int_variab, LSF_GAP, M);

   /* copy lsf to speech decoders lsf state */
   Copy(lsf_int, lsfState->past_lsf_q, M);

   /* convert to lsp */
   Lsf_lsp(lsf_int, lsp_int, M);
   Lsf_lsp(lsf_int_variab, lsp_int_variab, M);

   /* Compute acoeffs Q12 acoeff is used for level    * 
    * normalization and postfilter, acoeff_variab is  *
    * used for synthesis filter                       *
    * by doing this we make sure that the level       *
    * in high frequenncies does not jump up and down  */

   Lsp_Az(lsp_int, acoeff);
   Lsp_Az(lsp_int_variab, acoeff_variab);
   
   /* For use in postfilter */
   Copy(acoeff, &A_t[0],           M + 1);
   Copy(acoeff, &A_t[M + 1],       M + 1);
   Copy(acoeff, &A_t[2 * (M + 1)], M + 1);
   Copy(acoeff, &A_t[3 * (M + 1)], M + 1);
   
   /* Compute reflection coefficients Q15 */
   A_Refl(&acoeff[1], refl);
   
   /* Compute prediction error in Q15 */
   pred_err = MAX_16; /* 0.99997 in Q15 */                          move16();
   for (i = 0; i < M; i++)
   { 
      pred_err = mult(pred_err, sub(MAX_16, mult(refl[i], refl[i])));
   }

   /* compute logarithm of prediction gain */   
   Log2(L_deposit_l(pred_err), &log_pg_e, &log_pg_m);
   
   /* convert exponent and mantissa to Word16 Q12 */
   log_pg = shl(sub(log_pg_e,15), 12);  /* Q12 */                   move16();
   log_pg = shr(sub(0,add(log_pg, shr(log_pg_m, 15-12))), 1);       move16();
   st->log_pg_mean = add(mult(29491,st->log_pg_mean),
                         mult(3277, log_pg));                       move16();

   /* Compute interpolated log energy */
   L_log_en_int = L_shr(L_log_en_int, 10); /* Q26 -> Q16 */         move32();

   /* Add 4 in Q16 */
   L_log_en_int = L_add(L_log_en_int, 4 * 65536L);                  move32();

   /* subtract prediction gain */
   L_log_en_int = L_sub(L_log_en_int, L_shl(L_deposit_l(log_pg), 4));move32();

   /* adjust level to speech coder mode */
   L_log_en_int = L_add(L_log_en_int, 
                        L_shl(L_deposit_l(st->log_en_adjust), 5));  move32();
       
   log_en_int_e = extract_h(L_log_en_int);                    move16();
   move16();
   log_en_int_m = extract_l(L_shr(L_sub(L_log_en_int, 
                                        L_deposit_h(log_en_int_e)), 1));
   level = extract_l(Pow2(log_en_int_e, log_en_int_m)); /* Q4 */ move16();
   
   for (i = 0; i < 4; i++)
   {             
      /* Compute innovation vector */
      build_CN_code(&st->L_pn_seed_rx, ex);
      for (j = 0; j < L_SUBFR; j++)
      {
         ex[j] = mult(level, ex[j]);                                move16();
      }
      /* Synthesize */
      Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, 
               mem_syn, 1);
      
   } /* next i */
   
   /* reset codebook averaging variables */ 
   averState->hangVar = 20;                                         move16();
   averState->hangCount = 0;                                        move16();
    
   test();
   if (sub(new_state, DTX_MUTE) == 0)
   {
      /* mute comfort noise as it has been quite a long time since  
       * last SID update  was performed                            */
      
      tmp_int_length = st->since_last_sid;                          move16();
      test();
      if (sub(tmp_int_length, 32) > 0)
      {
         tmp_int_length = 32;                                       move16();
      }
      
      /* safety guard against division by zero */
      test();
      if(tmp_int_length <= 0) {
         tmp_int_length = 8;                                       move16();
      }      
      
      move16();
      st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); 

      st->since_last_sid = 0;                                       move16();
      Copy(st->lsp, st->lsp_old, M);
      st->old_log_en = st->log_en;                                  move16();
      /* subtract 1/8 in Q11 i.e -6/8 dB */
      st->log_en = sub(st->log_en, 256);                            move16();  
   }

   /* reset interpolation length timer 
    * if data has been updated.        */
   test(); test(); test(); test();
   if ((st->sid_frame != 0) && 
       ((st->valid_data != 0) || 
        ((st->valid_data == 0) &&  (st->dtxHangoverAdded) != 0))) 
   {
      st->since_last_sid =  0;                                      move16();
      st->data_updated = 1;                                         move16();
   }
         
   return 0;
}
Example #10
0
inline int Log2Int(float v) {
    return Floor2Int(Log2(v));
}
/*
 * Creates a vector of driver bundle info structures from the hot-plug driver
 * directory.
 *
 * Returns NULL on error and a pointer to an allocated HPDriver vector on
 * success.  The caller must free the HPDriver with a call to
 * HPDriversRelease().
 */
static HPDriverVector HPDriversGetFromDirectory(const char *driverBundlePath)
{
#ifdef DEBUG_HOTPLUG
	Log2(PCSC_LOG_DEBUG, "Entering HPDriversGetFromDirectory: %s",
		driverBundlePath);
#endif

	int readersNumber = 0;
	HPDriverVector bundleVector = NULL;
	CFArrayRef bundleArray;
	CFStringRef driverBundlePathString =
		CFStringCreateWithCString(kCFAllocatorDefault,
		driverBundlePath,
		kCFStringEncodingMacRoman);
	CFURLRef pluginUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
		driverBundlePathString,
		kCFURLPOSIXPathStyle, TRUE);

	CFRelease(driverBundlePathString);
	if (!pluginUrl)
	{
		Log1(PCSC_LOG_ERROR, "error getting plugin directory URL");
		return NULL;
	}
	bundleArray = CFBundleCreateBundlesFromDirectory(kCFAllocatorDefault,
		pluginUrl, NULL);
	if (!bundleArray)
	{
		Log1(PCSC_LOG_ERROR, "error getting plugin directory bundles");
		return NULL;
	}
	CFRelease(pluginUrl);

	size_t bundleArraySize = CFArrayGetCount(bundleArray);
	size_t i;

	/* get the number of readers (including aliases) */
	for (i = 0; i < bundleArraySize; i++)
	{
		CFBundleRef currBundle =
			(CFBundleRef) CFArrayGetValueAtIndex(bundleArray, i);
		CFDictionaryRef dict = CFBundleGetInfoDictionary(currBundle);

		const void * blobValue = CFDictionaryGetValue(dict,
			CFSTR(PCSCLITE_HP_MANUKEY_NAME));

		if (!blobValue)
		{
			Log1(PCSC_LOG_ERROR, "error getting vendor ID from bundle");
			return NULL;
		}

		if (CFGetTypeID(blobValue) == CFArrayGetTypeID())
		{
			/* alias found, each reader count as 1 */
			CFArrayRef propertyArray = blobValue;
			readersNumber += CFArrayGetCount(propertyArray);
		}
		else
			/* No alias, only one reader supported */
			readersNumber++;
	}
#ifdef DEBUG_HOTPLUG
	Log2(PCSC_LOG_DEBUG, "Total of %d readers supported", readersNumber);
#endif

	/* The last entry is an end marker (m_vendorId = 0)
	 * see checks in HPDriversMatchUSBDevices:503
	 *  and HPDriverVectorRelease:376 */
	readersNumber++;

	bundleVector = calloc(readersNumber, sizeof(HPDriver));
	if (!bundleVector)
	{
		Log1(PCSC_LOG_ERROR, "memory allocation failure");
		return NULL;
	}

	HPDriver *driverBundle = bundleVector;
	for (i = 0; i < bundleArraySize; i++)
	{
		CFBundleRef currBundle =
			(CFBundleRef) CFArrayGetValueAtIndex(bundleArray, i);
		CFDictionaryRef dict = CFBundleGetInfoDictionary(currBundle);

		CFURLRef bundleUrl = CFBundleCopyBundleURL(currBundle);
		CFStringRef bundlePath = CFURLCopyPath(bundleUrl);

		driverBundle->m_libPath = strdup(CFStringGetCStringPtr(bundlePath,
				CFStringGetSystemEncoding()));

		const void * blobValue = CFDictionaryGetValue(dict,
			CFSTR(PCSCLITE_HP_MANUKEY_NAME));

		if (!blobValue)
		{
			Log1(PCSC_LOG_ERROR, "error getting vendor ID from bundle");
			return bundleVector;
		}

		if (CFGetTypeID(blobValue) == CFArrayGetTypeID())
		{
			CFArrayRef vendorArray = blobValue;
			CFArrayRef productArray;
			CFArrayRef friendlyNameArray;
			char *libPath = driverBundle->m_libPath;

#ifdef DEBUG_HOTPLUG
			Log2(PCSC_LOG_DEBUG, "Driver with aliases: %s", libPath);
#endif
			/* get list of ProductID */
			productArray = CFDictionaryGetValue(dict,
				 CFSTR(PCSCLITE_HP_PRODKEY_NAME));
			if (!productArray)
			{
				Log1(PCSC_LOG_ERROR, "error getting product ID from bundle");
				return bundleVector;
			}

			/* get list of FriendlyName */
			friendlyNameArray = CFDictionaryGetValue(dict,
				 CFSTR(PCSCLITE_HP_NAMEKEY_NAME));
			if (!friendlyNameArray)
			{
				Log1(PCSC_LOG_ERROR, "error getting product ID from bundle");
				return bundleVector;
			}

			int reader_nb = CFArrayGetCount(vendorArray);

			if (reader_nb != CFArrayGetCount(productArray))
			{
				Log3(PCSC_LOG_ERROR,
					"Malformed Info.plist: %d vendors and %ld products",
					reader_nb, CFArrayGetCount(productArray));
				return bundleVector;
			}

			if (reader_nb != CFArrayGetCount(friendlyNameArray))
			{
				Log3(PCSC_LOG_ERROR,
					"Malformed Info.plist: %d vendors and %ld friendlynames",
					reader_nb, CFArrayGetCount(friendlyNameArray));
				return bundleVector;
			}

			int j;
			for (j=0; j<reader_nb; j++)
			{
				CFStringRef strValue = CFArrayGetValueAtIndex(vendorArray, j);

				driverBundle->m_vendorId = strtoul(CFStringGetCStringPtr(strValue,
					CFStringGetSystemEncoding()), NULL, 16);

				strValue = CFArrayGetValueAtIndex(productArray, j);
				driverBundle->m_productId = strtoul(CFStringGetCStringPtr(strValue,
					CFStringGetSystemEncoding()), NULL, 16);

				strValue = CFArrayGetValueAtIndex(friendlyNameArray, j);
				const char *cstr = CFStringGetCStringPtr(strValue,
					CFStringGetSystemEncoding());

				driverBundle->m_friendlyName = strdup(cstr);
				if (!driverBundle->m_libPath)
					driverBundle->m_libPath = strdup(libPath);

#ifdef DEBUG_HOTPLUG
				Log2(PCSC_LOG_DEBUG, "VendorID: 0x%04X",
					driverBundle->m_vendorId);
				Log2(PCSC_LOG_DEBUG, "ProductID: 0x%04X",
					driverBundle->m_productId);
				Log2(PCSC_LOG_DEBUG, "Friendly name: %s",
					driverBundle->m_friendlyName);
				Log2(PCSC_LOG_DEBUG, "Driver: %s", driverBundle->m_libPath);
#endif

				/* go to next bundle in the vector */
				driverBundle++;
			}
		}
		else
		{
			CFStringRef strValue = blobValue;

#ifdef DEBUG_HOTPLUG
			Log3(PCSC_LOG_DEBUG, "Driver without alias: %s %s",
				driverBundle->m_friendlyName, driverBundle->m_libPath);
#endif

			driverBundle->m_vendorId = strtoul(CFStringGetCStringPtr(strValue,
					CFStringGetSystemEncoding()), NULL, 16);

			strValue = (CFStringRef) CFDictionaryGetValue(dict,
				CFSTR(PCSCLITE_HP_PRODKEY_NAME));
			if (!strValue)
			{
				Log1(PCSC_LOG_ERROR, "error getting product ID from bundle");
				return bundleVector;
			}
			driverBundle->m_productId = strtoul(CFStringGetCStringPtr(strValue,
				CFStringGetSystemEncoding()), NULL, 16);

			strValue = (CFStringRef) CFDictionaryGetValue(dict,
				CFSTR(PCSCLITE_HP_NAMEKEY_NAME));
			if (!strValue)
			{
				Log1(PCSC_LOG_ERROR, "error getting product friendly name from bundle");
				driverBundle->m_friendlyName = strdup("unnamed device");
			}
			else
			{
				const char *cstr = CFStringGetCStringPtr(strValue,
					CFStringGetSystemEncoding());

				driverBundle->m_friendlyName = strdup(cstr);
			}
#ifdef DEBUG_HOTPLUG
			Log2(PCSC_LOG_DEBUG, "VendorID: 0x%04X", driverBundle->m_vendorId);
			Log2(PCSC_LOG_DEBUG, "ProductID: 0x%04X", driverBundle->m_productId);
			Log2(PCSC_LOG_DEBUG, "Friendly name: %s", driverBundle->m_friendlyName);
			Log2(PCSC_LOG_DEBUG, "Driver: %s", driverBundle->m_libPath);
#endif

			/* go to next bundle in the vector */
			driverBundle++;
		}
	}
	CFRelease(bundleArray);
	return bundleVector;
}
  unsigned long
  StaticRangeCoder::encodeIntVectorToStream (std::vector<unsigned int>& inputIntVector_arg,
                                             std::ostream& outputByteStream_arg)
  {

    unsigned int inputsymbol;
    unsigned int i, f;
    char out;

    unsigned long frequencyTableSize;
    uint8_t frequencyTableByteSize;

    // define numerical limits
    const uint64_t top = (uint64_t)1 << 56;
    const uint64_t bottom = (uint64_t)1 << 48;
    const uint64_t maxRange = (uint64_t)1 << 48;

    unsigned long input_size = inputIntVector_arg.size ();
    uint64_t low, range;

    unsigned int inputSymbol;

    unsigned int readPos;

    unsigned long streamByteCount;

    streamByteCount = 0;

    // init output vector
    outputCharVector_.clear();
    outputCharVector_.reserve(sizeof(char) * input_size * 2);

    frequencyTableSize = 1;

    readPos = 0;

    // calculate frequency table
    cFreqTable_[0] = cFreqTable_[1] = 0;
    while (readPos < input_size)
    {
      inputSymbol = inputIntVector_arg[readPos++];

      if (inputSymbol + 1 >= frequencyTableSize)
      {
        // frequency table is to small -> adaptively extend it
        unsigned long oldfrequencyTableSize;
        oldfrequencyTableSize = frequencyTableSize;

        do
        {
          // increase frequency table size by factor 2
          frequencyTableSize <<= 1;
        } while (inputSymbol + 1 > frequencyTableSize);

        if (cFreqTable_.size () < frequencyTableSize + 1)
        {
          // resize frequency vector
          cFreqTable_.resize (frequencyTableSize + 1);
        }

        // init new frequency range with zero
        memset (&cFreqTable_[oldfrequencyTableSize + 1], 0,
                sizeof(uint64_t) * (frequencyTableSize - oldfrequencyTableSize));
      }
      cFreqTable_[inputSymbol + 1]++;
    }
    frequencyTableSize++;

    // convert to cumulative frequency table
    for (f = 1; f < frequencyTableSize; f++)
    {
      cFreqTable_[f] = cFreqTable_[f - 1] + cFreqTable_[f];
      if (cFreqTable_[f] <= cFreqTable_[f - 1])
        cFreqTable_[f] = cFreqTable_[f - 1] + 1;
    }

    // rescale if numerical limits are reached
    while (cFreqTable_[frequencyTableSize - 1] >= maxRange)
    {
      for (f = 1; f < cFreqTable_.size (); f++)
      {
        cFreqTable_[f] /= 2;
        ;
        if (cFreqTable_[f] <= cFreqTable_[f - 1])
          cFreqTable_[f] = cFreqTable_[f - 1] + 1;
      }
    }

    // calculate amount of bytes per frequeny table entry
    frequencyTableByteSize = (uint8_t)ceil (Log2 (cFreqTable_[frequencyTableSize - 1]) / 8.0);

    // write size of frequency table to output stream
    outputByteStream_arg.write ((const char *)&frequencyTableSize, sizeof(frequencyTableSize));
    outputByteStream_arg.write ((const char *)&frequencyTableByteSize, sizeof(frequencyTableByteSize));

    streamByteCount += sizeof(frequencyTableSize)+sizeof(frequencyTableByteSize);

    // write cumulative  frequency table to output stream
    for (f = 1; f < frequencyTableSize; f++)
    {
      outputByteStream_arg.write ((const char *)&cFreqTable_[f], frequencyTableByteSize);
      streamByteCount += frequencyTableByteSize;
    }

    readPos = 0;
    low = 0;
    range = (uint64_t)-1;

    // start encoding
    while (readPos < input_size)
    {

      // read symol
      inputsymbol = inputIntVector_arg[readPos++];

      // map to range
      low += cFreqTable_[inputsymbol] * (range /= cFreqTable_[frequencyTableSize - 1]);
      range *= cFreqTable_[inputsymbol + 1] - cFreqTable_[inputsymbol];

      // check range limits
      while ((low ^ (low + range)) < top || ((range < bottom) && ((range = -low & (bottom - 1)), 1)))
      {
        out = low >> 56;
        range <<= 8;
        low <<= 8;
        outputCharVector_.push_back(out);
      }

    }

    // flush remaining data
    for (i = 0; i < 8; i++)
    {
      out = low >> 56;
      outputCharVector_.push_back(out);
      low <<= 8;
    }

    // write encoded data to stream
    outputByteStream_arg.write (&outputCharVector_[0], outputCharVector_.size());

    streamByteCount += outputCharVector_.size();

    return streamByteCount;

  }
Example #13
0
int VBoxNetBaseService::tryGoOnline(void)
{
    /*
     * Open the session, load ring-0 and issue the request.
     */
    int rc = SUPR3Init(&m_pSession);
    if (RT_FAILURE(rc))
    {
        m_pSession = NIL_RTR0PTR;
        LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc));
        return 1;
    }

    char szPath[RTPATH_MAX];
    rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/VMMR0.r0"));
    if (RT_FAILURE(rc))
    {
        LogRel(("VBoxNetBaseService: RTPathExecDir -> %Rrc\n", rc));
        return 1;
    }

    rc = SUPR3LoadVMM(strcat(szPath, "/VMMR0.r0"));
    if (RT_FAILURE(rc))
    {
        LogRel(("VBoxNetBaseService: SUPR3LoadVMM(\"%s\") -> %Rrc\n", szPath, rc));
        return 1;
    }

    /*
     * Create the open request.
     */
    PINTNETBUF pBuf;
    INTNETOPENREQ OpenReq;
    OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    OpenReq.Hdr.cbReq = sizeof(OpenReq);
    OpenReq.pSession = m_pSession;
    strncpy(OpenReq.szNetwork, m_Network.c_str(), sizeof(OpenReq.szNetwork));
    OpenReq.szNetwork[sizeof(OpenReq.szNetwork) - 1] = '\0';
    strncpy(OpenReq.szTrunk, m_TrunkName.c_str(), sizeof(OpenReq.szTrunk));
    OpenReq.szTrunk[sizeof(OpenReq.szTrunk) - 1] = '\0';
    OpenReq.enmTrunkType = m_enmTrunkType;
    OpenReq.fFlags = 0; /** @todo check this */
    OpenReq.cbSend = m_cbSendBuf;
    OpenReq.cbRecv = m_cbRecvBuf;
    OpenReq.hIf = INTNET_HANDLE_INVALID;

    /*
     * Issue the request.
     */
    Log2(("attempting to open/create network \"%s\"...\n", OpenReq.szNetwork));
    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
    if (RT_FAILURE(rc))
    {
        Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc));
        goto bad;
    }
    m_hIf = OpenReq.hIf;
    Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m_hIf));

    /*
     * Get the ring-3 address of the shared interface buffer.
     */
    INTNETIFGETBUFFERPTRSREQ GetBufferPtrsReq;
    GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    GetBufferPtrsReq.Hdr.cbReq = sizeof(GetBufferPtrsReq);
    GetBufferPtrsReq.pSession = m_pSession;
    GetBufferPtrsReq.hIf = m_hIf;
    GetBufferPtrsReq.pRing3Buf = NULL;
    GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR;
    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS, 0, &GetBufferPtrsReq.Hdr);
    if (RT_FAILURE(rc))
    {
        Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS,) failed, rc=%Rrc\n", rc));
        goto bad;
    }
    pBuf = GetBufferPtrsReq.pRing3Buf;
    Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
               pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv));
    m_pIfBuf = pBuf;

    /*
     * Activate the interface.
     */
    INTNETIFSETACTIVEREQ ActiveReq;
    ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    ActiveReq.Hdr.cbReq = sizeof(ActiveReq);
    ActiveReq.pSession = m_pSession;
    ActiveReq.hIf = m_hIf;
    ActiveReq.fActive = true;
    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr);
    if (RT_SUCCESS(rc))
        return 0;

    /* bail out */
    Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc));

    return 0;
    bad:
        return 1;
}
Example #14
0
/**
 * Parse the arguments.
 *
 * @returns 0 on success, fully bitched exit code on failure.
 *
 * @param   argc    Argument count.
 * @param   argv    Argument vector.
 */
int VBoxNetBaseService::parseArgs(int argc, char **argv)
{

    RTGETOPTSTATE State;
    PRTGETOPTDEF paOptionArray = getOptionsPtr();
    int rc = RTGetOptInit(&State, argc, argv, paOptionArray, m_vecOptionDefs.size(), 0, 0 /*fFlags*/);
    AssertRCReturn(rc, 49);
#if 0
    /* default initialization */
    m_enmTrunkType = kIntNetTrunkType_WhateverNone;
#endif
    Log2(("BaseService: parseArgs enter\n"));

    for (;;)
    {
        RTGETOPTUNION Val;
        rc = RTGetOpt(&State, &Val);
        if (!rc)
            break;
        switch (rc)
        {
            case 'N':
                m_Name = Val.psz;
                break;
            case 'n':
                m_Network = Val.psz;
                break;
            case 't':
                m_TrunkName = Val.psz;
                break;
            case 'T':
                if (!strcmp(Val.psz, "none"))
                    m_enmTrunkType = kIntNetTrunkType_None;
                else if (!strcmp(Val.psz, "whatever"))
                    m_enmTrunkType = kIntNetTrunkType_WhateverNone;
                else if (!strcmp(Val.psz, "netflt"))
                    m_enmTrunkType = kIntNetTrunkType_NetFlt;
                else if (!strcmp(Val.psz, "netadp"))
                    m_enmTrunkType = kIntNetTrunkType_NetAdp;
                else if (!strcmp(Val.psz, "srvnat"))
                    m_enmTrunkType = kIntNetTrunkType_SrvNat;
                else
                {
                    RTStrmPrintf(g_pStdErr, "Invalid trunk type '%s'\n", Val.psz);
                    return 1;
                }
                break;
            case 'a':
                m_MacAddress = Val.MacAddr;
                break;
            case 'i':
                m_Ipv4Address = Val.IPv4Addr;
                break;
        case 'm':
          m_Ipv4Netmask = Val.IPv4Addr;
          break;

            case 'v':
                m_cVerbosity++;
                break;

            case 'V':
                RTPrintf("%sr%u\n", RTBldCfgVersion(), RTBldCfgRevision());
                return 1;

            case 'h':
                RTPrintf("%s Version %sr%u\n"
                         "(C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
                         "All rights reserved.\n"
                         "\n"
                         "Usage: %s <options>\n"
                         "\n"
                         "Options:\n",
                         RTProcShortName(),
                         RTBldCfgVersion(),
                         RTBldCfgRevision(),
                         RTProcShortName());
                for (unsigned int i = 0; i < m_vecOptionDefs.size(); i++)
                    RTPrintf("    -%c, %s\n", m_vecOptionDefs[i]->iShort, m_vecOptionDefs[i]->pszLong);
                usage(); /* to print Service Specific usage */
                return 1;

            default:
                int rc1 = parseOpt(rc, Val);
                if (RT_FAILURE(rc1))
                {
                    rc = RTGetOptPrintError(rc, &Val);
                    RTPrintf("Use --help for more information.\n");
                    return rc;
                }
        }
    }

    RTMemFree(paOptionArray);
    return rc;
}
Example #15
0
/*---------------------------------------------------------------------------*
 * Function  Gain_predict                                                    *
 * ~~~~~~~~~~~~~~~~~~~~~~                                                    *
 * MA prediction is performed on the innovation energy (in dB with mean      *
 * removed).                                                                 *
 *---------------------------------------------------------------------------*/
void Gain_predict(
   Word16 past_qua_en[],/* (i) Q10 :Past quantized energies        */
   Word16 code[],       /* (i) Q13 :Innovative vector.             */
   Word16 L_subfr,      /* (i)     :Subframe length.               */
   Word16 *gcode0,      /* (o) Qxx :Predicted codebook gain        */
   Word16 *exp_gcode0   /* (o)     :Q-Format(gcode0)               */
)
{
   Word16  i, exp, frac;
   Word32  L_tmp;

  /*-------------------------------*
   * Energy coming from code       *
   *-------------------------------*/

   L_tmp = 0;
   for(i=0; i<L_subfr; i++)
     L_tmp = L_mac(L_tmp, code[i], code[i]);

  /*-----------------------------------------------------------------*
   *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *
   *  Note: mean_ener change from 36 dB to 30 dB because input/2     *
   *                                                                 *
   * = 30.0 - 10 log10( ener_code / lcode)  + 10log10(2^27)          *
   *                                          !!ener_code in Q27!!   *
   * = 30.0 - 3.0103 * log2(ener_code) + 10log10(40) + 10log10(2^27) *
   * = 30.0 - 3.0103 * log2(ener_code) + 16.02  + 81.278             *
   * = 127.298 - 3.0103 * log2(ener_code)                            *
   *-----------------------------------------------------------------*/

   Log2(L_tmp, &exp, &frac);               /* Q27->Q0 ^Q0 ^Q15       */
   L_tmp = Mpy_32_16(exp, frac, -24660);   /* Q0 Q15 Q13 -> ^Q14     */
                                           /* hi:Q0+Q13+1            */
                                           /* lo:Q15+Q13-15+1        */
                                           /* -24660[Q13]=-3.0103    */
   L_tmp = L_mac(L_tmp, 32588, 32);        /* 32588*32[Q14]=127.298  */

  /*-----------------------------------------------------------------*
   * Compute gcode0.                                                 *
   *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener    *
   *-----------------------------------------------------------------*/

   L_tmp = L_shl(L_tmp, 10);                      /* From Q14 to Q24 */
   for(i=0; i<4; i++)
     L_tmp = L_mac(L_tmp, pred[i], past_qua_en[i]); /* Q13*Q10 ->Q24 */

   *gcode0 = extract_h(L_tmp);                    /* From Q24 to Q8  */

  /*-----------------------------------------------------------------*
   * gcode0 = pow(10.0, gcode0/20)                                   *
   *        = pow(2, 3.3219*gcode0/20)                               *
   *        = pow(2, 0.166*gcode0)                                   *
   *-----------------------------------------------------------------*/

   L_tmp = L_mult(*gcode0, 5439);       /* *0.166 in Q15, result in Q24*/
   L_tmp = L_shr(L_tmp, 8);             /* From Q24 to Q16             */
   L_Extract(L_tmp, &exp, &frac);       /* Extract exponent of gcode0  */

   *gcode0 = extract_l(Pow2(14, frac)); /* Put 14 as exponent so that  */
                                        /* output of Pow2() will be:   */
                                        /* 16768 < Pow2() <= 32767     */
   *exp_gcode0 = sub(14,exp);
}
void EHStatusHandlerThread(PREADER_CONTEXT rContext)
{
	LONG rv;
	LPCSTR lpcReader;
	DWORD dwStatus, dwReaderSharing;
	DWORD dwCurrentState;
	int pageSize = SYS_GetPageSize();

	/*
	 * Zero out everything
	 */
	dwStatus = 0;
	dwReaderSharing = 0;
	dwCurrentState = 0;

	secdebug("pcscd", "EHStatusHandlerThread: rContext: 0x%p", rContext);
	lpcReader = rContext->lpcReader;

	PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(rContext->readerState);

	DWORD tmpCardAtrLength = MAX_ATR_SIZE;
	rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength);
	secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDStatusICC: %d [%04X]", rv, rv);

	if (dwStatus & SCARD_PRESENT)
	{
		tmpCardAtrLength = MAX_ATR_SIZE;
		rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength);

		/* the protocol is unset after a power on */
		rs->xcardProtocol(SCARD_PROTOCOL_UNSET);

		secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDPowerICC: %d [%04X]", rv, rv);

		if (rv == IFD_SUCCESS)
		{
			rs->xcardAtrLength(tmpCardAtrLength);

			dwStatus |= SCARD_PRESENT;
			dwStatus &= ~SCARD_ABSENT;
			dwStatus |= SCARD_POWERED;
			dwStatus |= SCARD_NEGOTIABLE;
			dwStatus &= ~SCARD_SPECIFIC;
			dwStatus &= ~SCARD_SWALLOWED;
			dwStatus &= ~SCARD_UNKNOWN;

			if (rs->xcardAtrLength() > 0)
			{
				LogXxd(PCSC_LOG_INFO, "Card ATR: ",
					rs->xcardAtr(),
					rs->xcardAtrLength());
			}
			else
				Log1(PCSC_LOG_INFO, "Card ATR: (NULL)");
		}
		else
		{
			dwStatus |= SCARD_PRESENT;
			dwStatus &= ~SCARD_ABSENT;
			dwStatus |= SCARD_SWALLOWED;
			dwStatus &= ~SCARD_POWERED;
			dwStatus &= ~SCARD_NEGOTIABLE;
			dwStatus &= ~SCARD_SPECIFIC;
			dwStatus &= ~SCARD_UNKNOWN;
			Log3(PCSC_LOG_ERROR, "Error powering up card: %d 0x%04X", rv, rv);
		}

		dwCurrentState = SCARD_PRESENT;
	}
	else
	{
		dwStatus |= SCARD_ABSENT;
		dwStatus &= ~SCARD_PRESENT;
		dwStatus &= ~SCARD_POWERED;
		dwStatus &= ~SCARD_NEGOTIABLE;
		dwStatus &= ~SCARD_SPECIFIC;
		dwStatus &= ~SCARD_SWALLOWED;
		dwStatus &= ~SCARD_UNKNOWN;
		rs->xcardAtrLength(0);
		rs->xcardProtocol(SCARD_PROTOCOL_UNSET);

		dwCurrentState = SCARD_ABSENT;
	}

	/*
	 * Set all the public attributes to this reader
	 */
	rs->xreaderState(dwStatus);
	dwReaderSharing = rContext->dwContexts;
	rs->sharing(dwReaderSharing);

	SYS_MMapSynchronize((void *) rContext->readerState, pageSize);

	while (1)
	{
		dwStatus = 0;

		// Defensive measure
		if (!rContext->vHandle)
		{
			// Exit and notify the caller
			secdebug("pcscd", "EHStatusHandlerThread: lost dynamic callbacks ??");
			ReaderContextUnlock(rContext);
			SYS_ThreadDetach(rContext->pthThread);
			SYS_ThreadExit(0);
		}

		DWORD tmpCardAtrLength = MAX_ATR_SIZE;
		rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength);

		if (rv != SCARD_S_SUCCESS)
		{
			Log2(PCSC_LOG_ERROR, "Error communicating to: %s", lpcReader);

			/*
			 * Set error status on this reader while errors occur
			 */

			DWORD readerStateTmp = rs->xreaderState();
			readerStateTmp &= ~SCARD_ABSENT;
			readerStateTmp &= ~SCARD_PRESENT;
			readerStateTmp &= ~SCARD_POWERED;
			readerStateTmp &= ~SCARD_NEGOTIABLE;
			readerStateTmp &= ~SCARD_SPECIFIC;
			readerStateTmp &= ~SCARD_SWALLOWED;
			readerStateTmp |= SCARD_UNKNOWN;
			rs->xcardAtrLength(0);
			rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
			rs->xreaderState(readerStateTmp);

			dwCurrentState = SCARD_UNKNOWN;

			SYS_MMapSynchronize((void *) rContext->readerState, pageSize);

			/*
			 * This code causes race conditions on G4's with USB
			 * insertion
			 */
			/*
			 * dwErrorCount += 1; SYS_Sleep(1);
			 */
			/*
			 * After 10 seconds of errors, try to reinitialize the reader
			 * This sometimes helps bring readers out of *crazy* states.
			 */
			/*
			 * if ( dwErrorCount == 10 ) { RFUnInitializeReader( rContext
			 * ); RFInitializeReader( rContext ); dwErrorCount = 0; }
			 */

			/*
			 * End of race condition code block
			 */
		}

		if (dwStatus & SCARD_ABSENT)
		{
			if (dwCurrentState == SCARD_PRESENT ||
				dwCurrentState == SCARD_UNKNOWN)
			{
				/*
				 * Change the status structure
				 */
				Log2(PCSC_LOG_INFO, "Card Removed From %s", lpcReader);
				/*
				 * Notify the card has been removed
				 */
				RFSetReaderEventState(rContext, SCARD_REMOVED);

				rs->xcardAtrLength(0);
				rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
				DWORD readerStateTmp = rs->xreaderState();
				readerStateTmp |= SCARD_ABSENT;
				readerStateTmp &= ~SCARD_UNKNOWN;
				readerStateTmp &= ~SCARD_PRESENT;
				readerStateTmp &= ~SCARD_POWERED;
				readerStateTmp &= ~SCARD_NEGOTIABLE;
				readerStateTmp &= ~SCARD_SWALLOWED;
				readerStateTmp &= ~SCARD_SPECIFIC;
				rs->xreaderState(readerStateTmp);
				dwCurrentState = SCARD_ABSENT;

				SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
			}

		}
		else if (dwStatus & SCARD_PRESENT)
		{
			if (dwCurrentState == SCARD_ABSENT ||
				dwCurrentState == SCARD_UNKNOWN)
			{
				/*
				 * Power and reset the card
				 */
				SYS_USleep(PCSCLITE_STATUS_WAIT);
				DWORD tmpCardAtrLength = MAX_ATR_SIZE;
				rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength);

				/* the protocol is unset after a power on */
				rs->xcardProtocol(SCARD_PROTOCOL_UNSET);

				secdebug("pcscd", "EHStatusHandlerThread: power-and-reset call to IFDPowerICC: %d [%04X]", rv, rv);

				DWORD readerStateTmp = rs->xreaderState();
				if (rv == IFD_SUCCESS)
				{
					rs->xcardAtrLength(tmpCardAtrLength);

					readerStateTmp |= SCARD_PRESENT;
					readerStateTmp &= ~SCARD_ABSENT;
					readerStateTmp |= SCARD_POWERED;
					readerStateTmp |= SCARD_NEGOTIABLE;
					readerStateTmp &= ~SCARD_SPECIFIC;
					readerStateTmp &= ~SCARD_UNKNOWN;
					readerStateTmp &= ~SCARD_SWALLOWED;
					rs->xreaderState(readerStateTmp);

					/*
					 * Notify the card has been reset
					 */
					RFSetReaderEventState(rContext, SCARD_RESET);
				}
				else
				{
					readerStateTmp |= SCARD_PRESENT;
					readerStateTmp &= ~SCARD_ABSENT;
					readerStateTmp |= SCARD_SWALLOWED;
					readerStateTmp &= ~SCARD_POWERED;
					readerStateTmp &= ~SCARD_NEGOTIABLE;
					readerStateTmp &= ~SCARD_SPECIFIC;
					readerStateTmp &= ~SCARD_UNKNOWN;
					rs->xreaderState(readerStateTmp);
					rs->xcardAtrLength(0);
				}

				dwCurrentState = SCARD_PRESENT;

				SYS_MMapSynchronize((void *) rContext->readerState, pageSize);

				Log2(PCSC_LOG_INFO, "Card inserted into %s", lpcReader);

				if (rv == IFD_SUCCESS)
				{
					if (rs->xcardAtrLength() > 0)
						LogXxd(PCSC_LOG_INFO, "Card ATR: ", rs->xcardAtr(), rs->xcardAtrLength());
					else
						Log1(PCSC_LOG_INFO, "Card ATR: (NULL)");
				}
				else
					Log1(PCSC_LOG_ERROR,"Error powering up card.");
			}
		}

		if (ReaderContextIsLocked(rContext))
		{
			/*
			 * Exit and notify the caller
			 */
			secdebug("pcscd", "EHStatusHandlerThread: parent requested shutdown");
			ReaderContextUnlock(rContext);
			SYS_ThreadDetach(rContext->pthThread);
			SYS_ThreadExit(0);
		}

		/*
		 * Sharing may change w/o an event pass it on
		 */

		if (dwReaderSharing != (uint32_t)rContext->dwContexts)
		{
			dwReaderSharing = rContext->dwContexts;
			rs->sharing(dwReaderSharing);
			SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
		}

		SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
	}
}
/**
 * @brief Creates threads to handle messages received from Clients.
 *
 * @param[in] pdwClientID Connection ID used to reference the Client.
 *
 * @return Error code.
 * @retval SCARD_S_SUCCESS Success.
 * @retval SCARD_F_INTERNAL_ERROR Exceded the maximum number of simultaneous Application Contexts.
 * @retval SCARD_E_NO_MEMORY Error creating the Context Thread.
 */
LONG CreateContextThread(uint32_t *pdwClientID)
{
	int rv;
	int lrv;
	int listSize;
	SCONTEXT * newContext = NULL;
	LONG retval = SCARD_E_NO_MEMORY;

	(void)pthread_mutex_lock(&contextsList_lock);

	listSize = list_size(&contextsList);
	if (listSize >= contextMaxThreadCounter)
	{
		Log2(PCSC_LOG_CRITICAL, "Too many context running: %d", listSize);
		goto out;
	}

	/* Create the context for this thread. */
	newContext = malloc(sizeof(*newContext));
	if (NULL == newContext)
	{
		Log1(PCSC_LOG_CRITICAL, "Could not allocate new context");
		goto out;
	}
	memset(newContext, 0, sizeof(*newContext));

	newContext->dwClientID = *pdwClientID;

	/* Initialise the list of card contexts */
	lrv = list_init(&newContext->cardsList);
	if (lrv < 0)
	{
		Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %d", lrv);
		goto out;
	}

	/* request to store copies, and provide the metric function */
	list_attributes_copy(&newContext->cardsList, list_meter_int32_t, 1);

	/* Adding a comparator
	 * The stored type is SCARDHANDLE (long) but has only 32 bits
	 * usefull even on a 64-bit CPU since the API between pcscd and
	 * libpcscliter uses "int32_t hCard;"
	 */
	lrv = list_attributes_comparator(&newContext->cardsList,
		list_comparator_int32_t);
	if (lrv != 0)
	{
		Log2(PCSC_LOG_CRITICAL,
			"list_attributes_comparator failed with return value: %d", lrv);
		list_destroy(&newContext->cardsList);
		goto out;
	}

	(void)pthread_mutex_init(&newContext->cardsList_lock, NULL);

	lrv = list_append(&contextsList, newContext);
	if (lrv < 0)
	{
		Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %d",
			lrv);
		list_destroy(&newContext->cardsList);
		goto out;
	}

	rv = ThreadCreate(&newContext->pthThread, THREAD_ATTR_DETACHED,
		(PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) newContext);
	if (rv)
	{
		int lrv2;

		Log2(PCSC_LOG_CRITICAL, "ThreadCreate failed: %s", strerror(rv));
		lrv2 = list_delete(&contextsList, newContext);
		if (lrv2 < 0)
			Log2(PCSC_LOG_CRITICAL, "list_delete failed with error %d", lrv2);
		list_destroy(&newContext->cardsList);
		goto out;
	}

	/* disable any suicide alarm */
	if (AutoExit)
		alarm(0);

	retval = SCARD_S_SUCCESS;

out:
	(void)pthread_mutex_unlock(&contextsList_lock);

	if (retval != SCARD_S_SUCCESS)
	{
		if (newContext)
			free(newContext);
		(void)close(*pdwClientID);
	}

	return retval;
}
/*
 * Ip input routine.  Checksum and byte swap header.  If fragmented
 * try to reassemble.  Process options.  Pass to next level.
 */
void
ip_input(PNATState pData, struct mbuf *m)
{
    register struct ip *ip;
    int hlen = 0;
    int mlen = 0;

    STAM_PROFILE_START(&pData->StatIP_input, a);

    LogFlowFunc(("ENTER: m = %lx\n", (long)m));
    ip = mtod(m, struct ip *);
    Log2(("ip_dst=%RTnaipv4(len:%d) m_len = %d\n", ip->ip_dst, RT_N2H_U16(ip->ip_len), m->m_len));

    ipstat.ips_total++;
    {
        int rc;
        STAM_PROFILE_START(&pData->StatALIAS_input, b);
        rc = LibAliasIn(select_alias(pData, m), mtod(m, char *), m_length(m, NULL));
        STAM_PROFILE_STOP(&pData->StatALIAS_input, b);
        Log2(("NAT: LibAlias return %d\n", rc));
        if (m->m_len != RT_N2H_U16(ip->ip_len))
            m->m_len = RT_N2H_U16(ip->ip_len);
    }

    mlen = m->m_len;

    if (mlen < sizeof(struct ip))
    {
        ipstat.ips_toosmall++;
        goto bad_free_m;
    }

    ip = mtod(m, struct ip *);
    if (ip->ip_v != IPVERSION)
    {
        ipstat.ips_badvers++;
        goto bad_free_m;
    }

    hlen = ip->ip_hl << 2;
    if (   hlen < sizeof(struct ip)
        || hlen > m->m_len)
    {
        /* min header length */
        ipstat.ips_badhlen++;                     /* or packet too short */
        goto bad_free_m;
    }

    /* keep ip header intact for ICMP reply
     * ip->ip_sum = cksum(m, hlen);
     * if (ip->ip_sum) {
     */
    if (cksum(m, hlen))
    {
        ipstat.ips_badsum++;
        goto bad_free_m;
    }

    /*
     * Convert fields to host representation.
     */
    NTOHS(ip->ip_len);
    if (ip->ip_len < hlen)
    {
        ipstat.ips_badlen++;
        goto bad_free_m;
    }

    NTOHS(ip->ip_id);
    NTOHS(ip->ip_off);

    /*
     * Check that the amount of data in the buffers
     * is as at least much as the IP header would have us expect.
     * Trim mbufs if longer than we expect.
     * Drop packet if shorter than we expect.
     */
    if (mlen < ip->ip_len)
    {
        ipstat.ips_tooshort++;
        goto bad_free_m;
    }

    /* Should drop packet if mbuf too long? hmmm... */
    if (mlen > ip->ip_len)
        m_adj(m, ip->ip_len - m->m_len);

    /* check ip_ttl for a correct ICMP reply */
    if (ip->ip_ttl==0 || ip->ip_ttl == 1)
    {
        icmp_error(pData, m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, "ttl");
        goto no_free_m;
    }

    ip->ip_ttl--;
    /*
     * If offset or IP_MF are set, must reassemble.
     * Otherwise, nothing need be done.
     * (We could look in the reassembly queue to see
     * if the packet was previously fragmented,
     * but it's not worth the time; just let them time out.)
     *
     */
    if (ip->ip_off & (IP_MF | IP_OFFMASK))
    {
        m = ip_reass(pData, m);
        if (m == NULL)
            goto no_free_m;
        ip = mtod(m, struct ip *);
        hlen = ip->ip_hl << 2;
    }
static LONG MSGRemoveContext(SCARDCONTEXT hContext, SCONTEXT * threadContext)
{
	LONG rv;
	int lrv;

	if (threadContext->hContext != hContext)
		return SCARD_E_INVALID_VALUE;

	(void)pthread_mutex_lock(&threadContext->cardsList_lock);
	while (list_size(&threadContext->cardsList) != 0)
	{
		READER_CONTEXT * rContext = NULL;
		SCARDHANDLE hCard, hLockId;
		void *ptr;

		/*
		 * Disconnect each of these just in case
		 */
		ptr = list_get_at(&threadContext->cardsList, 0);
		if (NULL == ptr)
		{
			Log1(PCSC_LOG_CRITICAL, "list_get_at failed");
			continue;
		}
		hCard = *(int32_t *)ptr;

		/*
		 * Unlock the sharing
		 */
		rv = RFReaderInfoById(hCard, &rContext);
		if (rv != SCARD_S_SUCCESS)
		{
			(void)pthread_mutex_unlock(&threadContext->cardsList_lock);
			return rv;
		}

		hLockId = rContext->hLockId;
		rContext->hLockId = 0;

		if (hCard != hLockId)
		{
			/*
			 * if the card is locked by someone else we do not reset it
			 * and simulate a card removal
			 */
			rv = SCARD_W_REMOVED_CARD;
		}
		else
		{
			/*
			 * We will use SCardStatus to see if the card has been
			 * reset there is no need to reset each time
			 * Disconnect is called
			 */
			rv = SCardStatus(hCard, NULL, NULL, NULL, NULL, NULL, NULL);
		}

		if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
			(void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
		else
			(void)SCardDisconnect(hCard, SCARD_RESET_CARD);

		/* Remove entry from the list */
		lrv = list_delete_at(&threadContext->cardsList, 0);
		if (lrv < 0)
			Log2(PCSC_LOG_CRITICAL,
				"list_delete_at failed with return value: %d", lrv);

		UNREF_READER(rContext)
	}
	(void)pthread_mutex_unlock(&threadContext->cardsList_lock);
	list_destroy(&threadContext->cardsList);

	/* We only mark the context as no longer in use.
	 * The memory is freed in MSGCleanupCLient() */
	threadContext->hContext = 0;

	return SCARD_S_SUCCESS;
}
/**
 * Read input and do some preprocessing.
 *
 * @returns VBox status.
 *          In addition to the iWrite and achInput, cInputLines is maintained.
 *          In case of an input overflow the fInputOverflow flag will be set.
 * @param   pDbgc   Debugger console instance data.
 */
static int dbgcInputRead(PDBGC pDbgc)
{
    /*
     * We have ready input.
     * Read it till we don't have any or we have a full input buffer.
     */
    int     rc = 0;
    do
    {
        /*
         * More available buffer space?
         */
        size_t cbLeft;
        if (pDbgc->iWrite > pDbgc->iRead)
            cbLeft = sizeof(pDbgc->achInput) - pDbgc->iWrite - (pDbgc->iRead == 0);
        else
            cbLeft = pDbgc->iRead - pDbgc->iWrite - 1;
        if (!cbLeft)
        {
            /* overflow? */
            if (!pDbgc->cInputLines)
                rc = dbgcInputOverflow(pDbgc);
            break;
        }

        /*
         * Read one char and interpret it.
         */
        char    achRead[128];
        size_t  cbRead;
        rc = pDbgc->pBack->pfnRead(pDbgc->pBack, &achRead[0], RT_MIN(cbLeft, sizeof(achRead)), &cbRead);
        if (RT_FAILURE(rc))
            return rc;
        char *psz = &achRead[0];
        while (cbRead-- > 0)
        {
            char ch = *psz++;
            switch (ch)
            {
                /*
                 * Ignore.
                 */
                case '\0':
                case '\r':
                case '\a':
                    break;

                /*
                 * Backspace.
                 */
                case '\b':
                    Log2(("DBGC: backspace\n"));
                    if (pDbgc->iRead != pDbgc->iWrite)
                    {
                        unsigned iWriteUndo = pDbgc->iWrite;
                        if (pDbgc->iWrite)
                            pDbgc->iWrite--;
                        else
                            pDbgc->iWrite = sizeof(pDbgc->achInput) - 1;

                        if (pDbgc->achInput[pDbgc->iWrite] == '\n')
                            pDbgc->iWrite = iWriteUndo;
                    }
                    break;

                /*
                 * Add char to buffer.
                 */
                case '\t':
                case '\n':
                case ';':
                    switch (ch)
                    {
                        case '\t': ch = ' '; break;
                        case '\n': pDbgc->cInputLines++; break;
                    }
                default:
                    Log2(("DBGC: ch=%02x\n", (unsigned char)ch));
                    pDbgc->achInput[pDbgc->iWrite] = ch;
                    if (++pDbgc->iWrite >= sizeof(pDbgc->achInput))
                        pDbgc->iWrite = 0;
                    break;
            }
        }

        /* Terminate it to make it easier to read in the debugger. */
        pDbgc->achInput[pDbgc->iWrite] = '\0';
    } while (pDbgc->pBack->pfnInput(pDbgc->pBack, 0));

    return rc;
}
int latch_overlay_check_latch(latch_overlay_config_data *cfg, char *id) {

    int rc = LATCH_STATUS_UNKNOWN;
    char *account_id = NULL;
    char *response = NULL;
    json_object *json_response = NULL;
    json_object *json_data = NULL;
    json_object *json_operations = NULL;
    json_object *json_application = NULL;
    json_bool json_application_rc = FALSE;
    json_object *json_status = NULL;

    Log1(LDAP_DEBUG_TRACE, LDAP_LEVEL_DEBUG, ">>> %s\n", __func__);

    if (latch_overlay_get_account_id(cfg, id, &account_id) != ERROR) {

        if (account_id != NULL) {

            Log2(LDAP_DEBUG_TRACE, LDAP_LEVEL_DEBUG, "    %s: account_id %s\n", __func__, account_id);

            if (cfg->operation_id == NULL) {
                response = status(account_id);
            } else {
                response = operationStatus(account_id, cfg->operation_id);
            }

            if (response != NULL) {

                Log2(LDAP_DEBUG_TRACE, LDAP_LEVEL_DEBUG, "    %s: response %s\n", __func__, response);

                json_response = json_tokener_parse(response);

                if (json_response != NULL) {

                    if ((json_object_object_get_ex(json_response, "data", &json_data) == TRUE) && (json_data != NULL)) {

                        if ((json_object_object_get_ex(json_data, "operations", &json_operations) == TRUE) && (json_operations != NULL)) {

                            if (cfg->operation_id == NULL) {
                                json_application_rc = json_object_object_get_ex(json_operations, cfg->application_id, &json_application);
                            } else {
                                json_application_rc = json_object_object_get_ex(json_operations, cfg->operation_id, &json_application);
                            }

                            if ((json_application_rc) == TRUE && (json_application != NULL)) {
                                if ((json_object_object_get_ex(json_application, "status", &json_status) == TRUE) && (json_status != NULL)) {
                                    if (json_object_get_string(json_status) != NULL && strcmp("off", json_object_get_string(json_status)) == 0) {
                                        rc = LATCH_STATUS_LOCKED;
                                    } else if (json_object_get_string(json_status) != NULL && strcmp("on", json_object_get_string(json_status)) == 0) {
                                        rc = LATCH_STATUS_UNLOCKED;
                                    }
                                }
                            }

                        }

                    }

                    json_object_put(json_response);

                }

                free(response);

            } else {
                Log1(LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "    %s: There has been an error communicating with the backend\n", __func__);
            }

            free(account_id);

            if ((rc == LATCH_STATUS_UNKNOWN) && (cfg->sdk_stop_on_error == 1)) {
                Log1(LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "    %s: No valid response from backend but is required. Returning LATCH_STATUS_LOCKED\n", __func__);
                rc = LATCH_STATUS_LOCKED;
            }

        } else {
            if (cfg->required == 1) {
                Log1(LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "    %s: User is not paired but Latch is required. Returning LATCH_STATUS_LOCKED\n", __func__);
                rc = LATCH_STATUS_LOCKED;
            }
        }

    } else {
        if (cfg->ldap_stop_on_error == 1) {
            Log1(LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "    %s: No valid response from the LDAP server but is required. Returning LATCH_STATUS_LOCKED\n", __func__);
            rc = LATCH_STATUS_LOCKED;
        }
    }

    Log1(LDAP_DEBUG_TRACE, LDAP_LEVEL_DEBUG, "<<< %s\n", __func__);

    return rc;

}
/*
 * Read from so's socket into sb_snd, updating all relevant sbuf fields
 * NOTE: This will only be called if it is select()ed for reading, so
 * a read() of 0 (or less) means it's disconnected
 */
int
soread(PNATState pData, struct socket *so)
{
    int n, nn, lss, total;
    struct sbuf *sb = &so->so_snd;
    size_t len = sb->sb_datalen - sb->sb_cc;
    struct iovec iov[2];
    int mss = so->so_tcpcb->t_maxseg;

    STAM_PROFILE_START(&pData->StatIOread, a);
    STAM_COUNTER_RESET(&pData->StatIORead_in_1);
    STAM_COUNTER_RESET(&pData->StatIORead_in_2);

    QSOCKET_LOCK(tcb);
    SOCKET_LOCK(so);
    QSOCKET_UNLOCK(tcb);

    LogFlow(("soread: so = %R[natsock]\n", so));
    Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", __PRETTY_FUNCTION__, so, sb));

    /*
     * No need to check if there's enough room to read.
     * soread wouldn't have been called if there weren't
     */

    len = sb->sb_datalen - sb->sb_cc;

    iov[0].iov_base = sb->sb_wptr;
    iov[1].iov_base = 0;
    iov[1].iov_len  = 0;
    if (sb->sb_wptr < sb->sb_rptr)
    {
        iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
        /* Should never succeed, but... */
        if (iov[0].iov_len > len)
            iov[0].iov_len = len;
        if (iov[0].iov_len > mss)
            iov[0].iov_len -= iov[0].iov_len%mss;
        n = 1;
    }
    else
    {
        iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
        /* Should never succeed, but... */
        if (iov[0].iov_len > len)
            iov[0].iov_len = len;
        len -= iov[0].iov_len;
        if (len)
        {
            iov[1].iov_base = sb->sb_data;
            iov[1].iov_len = sb->sb_rptr - sb->sb_data;
            if (iov[1].iov_len > len)
                iov[1].iov_len = len;
            total = iov[0].iov_len + iov[1].iov_len;
            if (total > mss)
            {
                lss = total % mss;
                if (iov[1].iov_len > lss)
                {
                    iov[1].iov_len -= lss;
                    n = 2;
                }
                else
                {
                    lss -= iov[1].iov_len;
                    iov[0].iov_len -= lss;
                    n = 1;
                }
            }
            else
                n = 2;
        }
        else
        {
            if (iov[0].iov_len > mss)
                iov[0].iov_len -= iov[0].iov_len%mss;
            n = 1;
        }
    }

#ifdef HAVE_READV
    nn = readv(so->s, (struct iovec *)iov, n);
#else
    nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, (so->so_tcpcb->t_force? MSG_OOB:0));
#endif
    Log2(("%s: read(1) nn = %d bytes\n", __PRETTY_FUNCTION__, nn));
    Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", __PRETTY_FUNCTION__, so, sb));
    if (nn <= 0)
    {
        /*
         * Special case for WSAEnumNetworkEvents: If we receive 0 bytes that
         * _could_ mean that the connection is closed. But we will receive an
         * FD_CLOSE event later if the connection was _really_ closed. With
         * www.youtube.com I see this very often. Closing the socket too early
         * would be dangerous.
         */
        int status;
        unsigned long pending = 0;
        status = ioctlsocket(so->s, FIONREAD, &pending);
        if (status < 0)
            Log(("NAT:%s: error in WSAIoctl: %d\n", __PRETTY_FUNCTION__, errno));
        if (nn == 0 && (pending != 0))
        {
            SOCKET_UNLOCK(so);
            STAM_PROFILE_STOP(&pData->StatIOread, a);
            return 0;
        }
        if (   nn < 0
            && soIgnorableErrorCode(errno))
        {
            SOCKET_UNLOCK(so);
            STAM_PROFILE_STOP(&pData->StatIOread, a);
            return 0;
        }
        else
        {
            int fUninitiolizedTemplate = 0;
            fUninitiolizedTemplate = RT_BOOL((   sototcpcb(so)
                                              && (  sototcpcb(so)->t_template.ti_src.s_addr == INADDR_ANY
                                                 || sototcpcb(so)->t_template.ti_dst.s_addr == INADDR_ANY)));
            /* nn == 0 means peer has performed an orderly shutdown */
            Log2(("%s: disconnected, nn = %d, errno = %d (%s)\n",
                  __PRETTY_FUNCTION__, nn, errno, strerror(errno)));
            sofcantrcvmore(so);
            if (!fUninitiolizedTemplate)
                tcp_sockclosed(pData, sototcpcb(so));
            else
                tcp_drop(pData, sototcpcb(so), errno);
            SOCKET_UNLOCK(so);
            STAM_PROFILE_STOP(&pData->StatIOread, a);
            return -1;
        }
    }
    STAM_STATS(
        if (n == 1)
        {
            STAM_COUNTER_INC(&pData->StatIORead_in_1);
            STAM_COUNTER_ADD(&pData->StatIORead_in_1_bytes, nn);
        }
        else
        {
            STAM_COUNTER_INC(&pData->StatIORead_in_2);
            STAM_COUNTER_ADD(&pData->StatIORead_in_2_1st_bytes, nn);
        }
    );
Example #23
0
/* m->m_data  points at ip packet header
 * m->m_len   length ip packet
 * ip->ip_len length data (IPDU)
 */
void
udp_input(PNATState pData, register struct mbuf *m, int iphlen)
{
    register struct ip *ip;
    register struct udphdr *uh;
    int len;
    struct ip save_ip;
    struct socket *so;
    int ret;
    int ttl, tos;

    LogFlowFunc(("ENTER: m = %p, iphlen = %d\n", m, iphlen));
    ip = mtod(m, struct ip *);
    Log2(("%RTnaipv4 iphlen = %d\n", ip->ip_dst, iphlen));

    udpstat.udps_ipackets++;

    /*
     * Strip IP options, if any; should skip this,
     * make available to user, and use on returned packets,
     * but we don't yet have a way to check the checksum
     * with options still present.
     */
    if (iphlen > sizeof(struct ip))
    {
        ip_stripoptions(m, (struct mbuf *)0);
        iphlen = sizeof(struct ip);
    }

    /*
     * Get IP and UDP header together in first mbuf.
     */
    ip = mtod(m, struct ip *);
    uh = (struct udphdr *)((caddr_t)ip + iphlen);

    /*
     * Make mbuf data length reflect UDP length.
     * If not enough data to reflect UDP length, drop.
     */
    len = RT_N2H_U16((u_int16_t)uh->uh_ulen);
    Assert(ip->ip_len + iphlen == (ssize_t)m_length(m, NULL));

    if (ip->ip_len != len)
    {
        if (len > ip->ip_len)
        {
            udpstat.udps_badlen++;
            Log3(("NAT: IP(id: %hd) has bad size\n", ip->ip_id));
            goto bad_free_mbuf;
        }
        m_adj(m, len - ip->ip_len);
        ip->ip_len = len;
    }

    /*
     * Save a copy of the IP header in case we want restore it
     * for sending an ICMP error message in response.
     */
    save_ip = *ip;
    save_ip.ip_len+= iphlen;         /* tcp_input subtracts this */

    /*
     * Checksum extended UDP header and data.
     */
    if (udpcksum && uh->uh_sum)
    {
        memset(((struct ipovly *)ip)->ih_x1, 0, 9);
        ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
#if 0
        /* keep uh_sum for ICMP reply */
        uh->uh_sum = cksum(m, len + sizeof (struct ip));
        if (uh->uh_sum)
        {

#endif
            if (cksum(m, len + iphlen))
            {
                udpstat.udps_badsum++;
                Log3(("NAT: IP(id: %hd) has bad (udp) cksum\n", ip->ip_id));
                goto bad_free_mbuf;
            }
        }
#if 0
    }
#endif

    /*
     *  handle DHCP/BOOTP
     */
    if (uh->uh_dport == RT_H2N_U16_C(BOOTP_SERVER))
    {
        bootp_input(pData, m);
        goto done_free_mbuf;
    }

    LogFunc(("uh src: %RTnaipv4:%d, dst: %RTnaipv4:%d\n",
             ip->ip_src.s_addr, RT_N2H_U16(uh->uh_sport),
             ip->ip_dst.s_addr, RT_N2H_U16(uh->uh_dport)));

    /*
     * handle DNS host resolver without creating a socket
     */
    if (   pData->fUseHostResolver
        && uh->uh_dport == RT_H2N_U16_C(53)
        && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS))
    {
        struct sockaddr_in dst, src;

        src.sin_addr.s_addr = ip->ip_dst.s_addr;
        src.sin_port = uh->uh_dport;
        dst.sin_addr.s_addr = ip->ip_src.s_addr;
        dst.sin_port = uh->uh_sport;

        m_adj(m, sizeof(struct udpiphdr));

        m = hostresolver(pData, m, ip->ip_src.s_addr, uh->uh_sport);
        if (m == NULL)
            goto done_free_mbuf;

        slirpMbufTagService(pData, m, CTL_DNS);

        udp_output2(pData, NULL, m, &src, &dst, IPTOS_LOWDELAY);
        LogFlowFuncLeave();
        return;
    }

    /*
     *  handle TFTP
     */
    if (   uh->uh_dport == RT_H2N_U16_C(TFTP_SERVER)
        && CTL_CHECK(ip->ip_dst.s_addr, CTL_TFTP))
    {
        if (pData->pvTftpSessions)
            slirpTftpInput(pData, m);
        goto done_free_mbuf;
    }

    /*
     * XXX: DNS proxy currently relies on the fact that each socket
     * only serves one request.
     */
    if (   pData->fUseDnsProxy
        && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS)
        && (uh->uh_dport == RT_H2N_U16_C(53)))
    {
        so = NULL;
        goto new_socket;
    }

    /*
     * Locate pcb for datagram.
     */
    so = udp_last_so;
    if (   so->so_lport != uh->uh_sport
        || so->so_laddr.s_addr != ip->ip_src.s_addr)
    {
        struct socket *tmp;

        for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next)
        {
            if (   tmp->so_lport        == uh->uh_sport
                && tmp->so_laddr.s_addr == ip->ip_src.s_addr)
            {
                so = tmp;
                break;
            }
        }
        if (tmp == &udb)
            so = NULL;
        else
        {
            udpstat.udpps_pcbcachemiss++;
            udp_last_so = so;
        }
    }

  new_socket:
    if (so == NULL)
    {
        /*
         * If there's no socket for this packet,
         * create one
         */
        if ((so = socreate()) == NULL)
        {
            Log2(("NAT: IP(id: %hd) failed to create socket\n", ip->ip_id));
            goto bad_free_mbuf;
        }
        if (udp_attach(pData, so) <= 0)
        {
            Log2(("NAT: IP(id: %hd) udp_attach errno = %d (%s)\n",
                        ip->ip_id, errno, strerror(errno)));
            sofree(pData, so);
            goto bad_free_mbuf;
        }

        /*
         * Setup fields
         */
        /* udp_last_so = so; */
        so->so_laddr = ip->ip_src;
        so->so_lport = uh->uh_sport;

        so->so_iptos = ip->ip_tos;

        /*
         * XXXXX Here, check if it's in udpexec_list,
         * and if it is, do the fork_exec() etc.
         */
    }

    so->so_faddr = ip->ip_dst;   /* XXX */
    so->so_fport = uh->uh_dport; /* XXX */
    Assert(so->so_type == IPPROTO_UDP);

    /*
     * DNS proxy
     */
    if (   pData->fUseDnsProxy
        && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS)
        && (uh->uh_dport == RT_H2N_U16_C(53)))
    {
        dnsproxy_query(pData, so, m, iphlen);
        goto done_free_mbuf;
    }

    iphlen += sizeof(struct udphdr);
    m->m_len -= iphlen;
    m->m_data += iphlen;

    ttl = ip->ip_ttl = save_ip.ip_ttl;
    if (ttl != so->so_sottl) {
        ret = setsockopt(so->s, IPPROTO_IP, IP_TTL,
                         (char *)&ttl, sizeof(ttl));
        if (RT_LIKELY(ret == 0))
            so->so_sottl = ttl;
    }

    tos = save_ip.ip_tos;
    if (tos != so->so_sotos) {
        ret = setsockopt(so->s, IPPROTO_IP, IP_TOS,
                         (char *)&tos, sizeof(tos));
        if (RT_LIKELY(ret == 0))
            so->so_sotos = tos;
    }

    {
        /*
         * Different OSes have different socket options for DF.  We
         * can't use IP_HDRINCL here as it's only valid for SOCK_RAW.
         */
#     define USE_DF_OPTION(_Optname) \
        const int dfopt = _Optname
#if   defined(IP_MTU_DISCOVER)
        USE_DF_OPTION(IP_MTU_DISCOVER);
#elif defined(IP_DONTFRAG)      /* Solaris 11+, FreeBSD */
        USE_DF_OPTION(IP_DONTFRAG);
#elif defined(IP_DONTFRAGMENT)  /* Windows */
        USE_DF_OPTION(IP_DONTFRAGMENT);
#else
        USE_DF_OPTION(0);
#endif
        if (dfopt) {
            int df = (save_ip.ip_off & IP_DF) != 0;
#if defined(IP_MTU_DISCOVER)
            df = df ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
#endif
            if (df != so->so_sodf) {
                ret = setsockopt(so->s, IPPROTO_IP, dfopt,
                                 (char *)&df, sizeof(df));
                if (RT_LIKELY(ret == 0))
                    so->so_sodf = df;
            }
        }
    }

    if (   sosendto(pData, so, m) == -1
        && (   !soIgnorableErrorCode(errno)
            && errno != ENOTCONN))
    {
        m->m_len += iphlen;
        m->m_data -= iphlen;
        *ip = save_ip;
        Log2(("NAT: UDP tx errno = %d (%s) on sent to %RTnaipv4\n",
              errno, strerror(errno), ip->ip_dst));
	icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
        so->so_m = NULL;
        LogFlowFuncLeave();
        return;
    }

    if (so->so_m)
        m_freem(pData, so->so_m);   /* used for ICMP if error on sorecvfrom */

    /* restore the orig mbuf packet */
    m->m_len += iphlen;
    m->m_data -= iphlen;
    *ip = save_ip;
    so->so_m = m;         /* ICMP backup */
    LogFlowFuncLeave();
    return;

bad_free_mbuf:
    Log2(("NAT: UDP(id: %hd) datagram to %RTnaipv4 with size(%d) claimed as bad\n",
        ip->ip_id, &ip->ip_dst, ip->ip_len));

done_free_mbuf:
    /* some services like bootp(built-in), dns(buildt-in) and dhcp don't need sockets
     * and create new m'buffers to send them to guest, so we'll free their incomming
     * buffers here.
     */
    if (m != NULL)
        m_freem(pData, m);
    LogFlowFuncLeave();
    return;
}
Example #24
0
File: init.c Project: dago/openldap
static int
relay_back_cf( ConfigArgs *c )
{
	relay_back_info	*ri = ( relay_back_info * )c->be->be_private;
	int		rc = 0;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		if ( ri != NULL && !BER_BVISNULL( &ri->ri_realsuffix ) ) {
			value_add_one( &c->rvalue_vals, &ri->ri_realsuffix );
			return 0;
		}
		return 1;

	} else if ( c->op == LDAP_MOD_DELETE ) {
		if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
			ch_free( ri->ri_realsuffix.bv_val );
			BER_BVZERO( &ri->ri_realsuffix );
			ri->ri_bd = NULL;
			return 0;
		}
		return 1;

	} else {
		BackendDB *bd;

		assert( ri != NULL );
		assert( BER_BVISNULL( &ri->ri_realsuffix ) );

		if ( c->be->be_nsuffix == NULL ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"\"relay\" directive "
				"must appear after \"suffix\"" );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			rc = 1;
			goto relay_done;
		}

		if ( !BER_BVISNULL( &c->be->be_nsuffix[ 1 ] ) ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"relaying of multiple suffix "
				"database not supported" );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			rc = 1;
			goto relay_done;
		}

		bd = select_backend( &c->value_ndn, 1 );
		if ( bd == NULL ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"cannot find database "
				"of relay dn \"%s\" "
				"in \"olcRelay <dn>\"\n",
				c->value_dn.bv_val );
			Log2( LDAP_DEBUG_CONFIG, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );

		} else if ( bd->be_private == c->be->be_private ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"relay dn \"%s\" would call self "
				"in \"relay <dn>\" line\n",
				c->value_dn.bv_val );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			rc = 1;
			goto relay_done;
		}

		ri->ri_realsuffix = c->value_ndn;
		BER_BVZERO( &c->value_ndn );

relay_done:;
		ch_free( c->value_dn.bv_val );
		ch_free( c->value_ndn.bv_val );
	}

	return rc;
}
INTERNAL int32_t SHMProcessEventsServer(uint32_t *pdwClientID)
{
	fd_set read_fd;
	int selret;
#ifdef DO_TIMEOUT
	struct timeval tv;

	tv.tv_sec = 1;
	tv.tv_usec = 0;
#endif

	FD_ZERO(&read_fd);

	/*
	 * Set up the bit masks for select
	 */
	FD_SET(commonSocket, &read_fd);

	selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
		(fd_set *) NULL,
#ifdef DO_TIMEOUT
		&tv
#else
		NULL
#endif
		);

	if (selret < 0)
	{
		if (EINTR == errno)
			return -2;

		Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
			strerror(errno));
		return -1;
	}

	if (selret == 0)
		/* timeout. On *BSD only */
		return 2;

	/*
	 * A common pipe packet has arrived - it could be a new application
	 */
	if (FD_ISSET(commonSocket, &read_fd))
	{
		Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
		if (SHMProcessCommonChannelRequest(pdwClientID) == -1)
		{
			Log2(PCSC_LOG_ERROR,
				"error in SHMProcessCommonChannelRequest: %d", *pdwClientID);
			return -1;
		}
	}
	else
		return -1;

	Log2(PCSC_LOG_DEBUG,
		"SHMProcessCommonChannelRequest detects: %d", *pdwClientID);

	return 0;
}
Example #26
0
int deliver_message (struct output_handler *handler, char *msg)
{
	struct timeval timeout;
	int todo, retry, msglen, s;
	fd_set fds;

	/* Initialize variables */
	FD_ZERO(&fds);
	todo = msglen = strlen(msg);
	retry = handler->retry;

	/* Try to send the message with reasonable effort */
	while (retry > 0)
	{
		/* If not connected, connect */
		if (handler->state == os_disconnected)
		{
			handler->connect(handler);
		}

		/* If valid filedescriptor, listen for signals */
		if (handler->fd != -1)
		{
			/* Add the handler's fd to the watchlist */
			FD_SET(handler->fd, &fds);
		}
		
		/* Set maximum timeout */
		timeout.tv_sec  = 30;
		timeout.tv_usec = 0;

		/* Perform select */
		if (handler->state == os_ready || handler->state == os_sending)
			s = select(handler->fd + 1, NULL, &fds, NULL, &timeout);
		else
		{
			timeout.tv_sec = 5;
			s = select(0, NULL, NULL, NULL, &timeout);
		}
		
		/* Determine select status */
		switch(s)
		{
			/* Error occured */
			case -1:
				SysErr(errno, "While doing select for message sending");
				return 0;

			/* Timeout occured */
			case 0:
				Log2(warning, "Output handling timeout", "[output.c]{deliver_message}");
				retry--;
				break;

			/* Activity on filedescriptor */
			default:
				Log2(warning, "Output is active", "[output.c]{deliver_message}");
				switch (handler->state)
				{
					/* Try to connect */
					case os_disconnected:
						CustomLog(__FILE__, __LINE__, warning, "Trying to connect output channel!");
						handler->connect(handler);
						break;
						
					/* Check if connection is established */
					case os_connecting:
						CustomLog(__FILE__, __LINE__, warning, "Still connecting output channel!");
						handler->connect(handler);
						break;
					
					/* Try to send the message */
					case os_ready:
					case os_sending:
						retry = 3;
						CustomLog(__FILE__, __LINE__, warning, "Trying to send message(msg=%p, msglen=%d, cont=%p)!", msg, msglen, todo);
						if (FD_ISSET(handler->fd, &fds) && handler->write(handler, msg, msglen, &todo))
						{
							/* Write succesfully completed */
							return 1;
						}
						break;
						
					/* Do a reset */
					case os_error:
						CustomLog(__FILE__, __LINE__, warning, "Resetting output channel!");
						break;
						
					/* Impossible */
					default:
						Log2(impossible, "IMPOSSIBLE state", "[output.c]{deliver_message}");
						return 0;
				}

				/* Continue */
				break;
		}
		
		/* If we're in error state, disconnect */
		if (handler->state == os_error)
		{
			SysErr(handler->err, "[output.c]{deliver_message} Handler is in an error state");
			handler->disconnect(handler);
			retry --;
		}
	}

	/* Out of retry's */
	Log(error, "Maximum amount of retry's reached");
	return 0;
}
Example #27
0
StreamBuffer::StreamBuffer(u32 type, u32 size)
: m_buffer(genBuffer()), m_buffertype(type), m_size(ROUND_UP_POW2(size)), m_bit_per_slot(Log2(ROUND_UP_POW2(size) / SYNC_POINTS))
{
	m_iterator = 0;
	m_used_iterator = 0;
	m_free_iterator = 0;
}
Example #28
0
// (8.6.2) and (8.6.3)
void scale_coefficients(decoder_context* ctx, slice_segment_header* shdr,
                        int xT,int yT, int nT, int cIdx)
{
    seq_parameter_set* sps = ctx->current_sps;

    int qP;
    switch (cIdx) {
    case 0:
        qP = shdr->qPYPrime;
        break;
    case 1:
        qP = shdr->qPCbPrime;
        break;
    case 2:
        qP = shdr->qPCrPrime;
        break;
    default:
        qP = 0;
        assert(0);
        break; // should never happen
    }

    logtrace(LogTransform,"qP: %d\n",qP);

    int16_t* coeff;
    int      coeffStride;
    get_coeff_plane(ctx,cIdx, &coeff,&coeffStride);


    if (shdr->cu_transquant_bypass_flag) {
        assert(false); // TODO
    }
    else {
        // (8.6.3)

        int bdShift = (cIdx==0 ? sps->BitDepth_Y : sps->BitDepth_C) + Log2(nT) - 5;

        logtrace(LogTransform,"coefficients IN:\n");
        for (int y=0; y<nT; y++) {
            logtrace(LogTransform,"  ");
            for (int x=0; x<nT; x++) {
                logtrace(LogTransform,"*%3d ", coeff[x+xT+(y+yT)*coeffStride]);
            }
            logtrace(LogTransform,"*\n");
        }

        if (sps->scaling_list_enable_flag==0) {
            for (int y=0; y<nT; y++)
                for (int x=0; x<nT; x++) {
                    coeff[xT+x+(y+yT)*coeffStride] = Clip3(-32768,32767,
                                                           ( (coeff[x+xT+(y+yT)*coeffStride]
                                                                   * 16 * levelScale[qP%6] << (qP/6))
                                                                   + (1<<(bdShift-1)) ) >> bdShift);
                }
        }
        else {
            assert(false); // TODO
        }

        logtrace(LogTransform,"coefficients OUT:\n");
        for (int y=0; y<nT; y++) {
            logtrace(LogTransform,"  ");
            for (int x=0; x<nT; x++) {
                logtrace(LogTransform,"*%3d ", coeff[x+xT+(y+yT)*coeffStride]);
            }
            logtrace(LogTransform,"*\n");
        }

        int bdShift2 = (cIdx==0) ? 20-sps->BitDepth_Y : 20-sps->BitDepth_C;

        if (get_transform_skip_flag(ctx,xT,yT,cIdx)) {
            for (int y=0; y<nT; y++)
                for (int x=0; x<nT; x++) {
                    int16_t c = coeff[x+xT+(y+yT)*coeffStride] << 7;
                    coeff[x+xT+(y+yT)*coeffStride] = (c+(1<<(bdShift2-1)))>>bdShift2;
                }
        }
        else {
Example #29
0
static int
dds_expire( void *ctx, dds_info_t *di )
{
	Connection	conn = { 0 };
	OperationBuffer opbuf;
	Operation	*op;
	slap_callback	sc = { 0 };
	dds_cb_t	dc = { 0 };
	dds_expire_t	*de = NULL, **dep;
	SlapReply	rs = { REP_RESULT };

	time_t		expire;
	char		tsbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
	struct berval	ts;

	int		ndeletes, ntotdeletes;

	int		rc;
	char		*extra = "";

	connection_fake_init2( &conn, &opbuf, ctx, 0 );
	op = &opbuf.ob_op;

	op->o_tag = LDAP_REQ_SEARCH;
	memset( &op->oq_search, 0, sizeof( op->oq_search ) );

	op->o_bd = select_backend( &di->di_nsuffix[ 0 ], 0 );

	op->o_req_dn = op->o_bd->be_suffix[ 0 ];
	op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ];

	op->o_dn = op->o_bd->be_rootdn;
	op->o_ndn = op->o_bd->be_rootndn;

	op->ors_scope = LDAP_SCOPE_SUBTREE;
	op->ors_tlimit = DDS_INTERVAL( di )/2 + 1;
	op->ors_slimit = SLAP_NO_LIMIT;
	op->ors_attrs = slap_anlist_no_attrs;

	expire = slap_get_time() - di->di_tolerance;
	ts.bv_val = tsbuf;
	ts.bv_len = sizeof( tsbuf );
	slap_timestamp( &expire, &ts );

	op->ors_filterstr.bv_len = STRLENOF( "(&(objectClass=" ")(" "<=" "))" )
		+ slap_schema.si_oc_dynamicObject->soc_cname.bv_len
		+ ad_entryExpireTimestamp->ad_cname.bv_len
		+ ts.bv_len;
	op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx );
	snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1,
		"(&(objectClass=%s)(%s<=%s))",
		slap_schema.si_oc_dynamicObject->soc_cname.bv_val,
		ad_entryExpireTimestamp->ad_cname.bv_val, ts.bv_val );

	op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );
	if ( op->ors_filter == NULL ) {
		rs.sr_err = LDAP_OTHER;
		goto done_search;
	}

	op->o_callback = &sc;
	sc.sc_response = dds_expire_cb;
	sc.sc_private = &dc;

	(void)op->o_bd->bd_info->bi_op_search( op, &rs );

done_search:;
	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
	filter_free_x( op, op->ors_filter, 1 );

	rc = rs.sr_err;
	switch ( rs.sr_err ) {
	case LDAP_SUCCESS:
		break;

	case LDAP_NO_SUCH_OBJECT:
		/* (ITS#5267) database not created yet? */
		rs.sr_err = LDAP_SUCCESS;
		extra = " (ignored)";
		/* fallthru */

	default:
		Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
			"DDS expired objects lookup failed err=%d%s\n",
			rc, extra );
		goto done;
	}

	op->o_tag = LDAP_REQ_DELETE;
	op->o_callback = &sc;
	sc.sc_response = slap_null_cb;
	sc.sc_private = NULL;

	slap_biglock_acquire(op->o_bd);
	for ( ntotdeletes = 0, ndeletes = 1; dc.dc_ndnlist != NULL  && ndeletes > 0; ) {
		ndeletes = 0;

		for ( dep = &dc.dc_ndnlist; *dep != NULL; ) {
			de = *dep;

			op->o_req_dn = de->de_ndn;
			op->o_req_ndn = de->de_ndn;
			(void)op->o_bd->bd_info->bi_op_delete( op, &rs );
			switch ( rs.sr_err ) {
			case LDAP_SUCCESS:
				Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
					"DDS dn=\"%s\" expired.\n",
					de->de_ndn.bv_val );
				ndeletes++;
				break;

			case LDAP_NOT_ALLOWED_ON_NONLEAF:
				Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE,
					"DDS dn=\"%s\" is non-leaf; "
					"deferring.\n",
					de->de_ndn.bv_val );
				dep = &de->de_next;
				de = NULL;
				break;

			default:
				Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE,
					"DDS dn=\"%s\" err=%d; "
					"deferring.\n",
					de->de_ndn.bv_val, rs.sr_err );
				break;
			}

			if ( de != NULL ) {
				*dep = de->de_next;
				op->o_tmpfree( de, op->o_tmpmemctx );
			}
		}

		ntotdeletes += ndeletes;
	}
	slap_biglock_release(op->o_bd);

	rs.sr_err = LDAP_SUCCESS;

	Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
		"DDS expired=%d\n", ntotdeletes );

done:;
	return rs.sr_err;
}
Example #30
0
/**
 * 32-bit write to a HPET timer register.
 *
 * @returns Strict VBox status code.
 *
 * @param   pThis           The HPET state.
 * @param   idxReg          The register being written to.
 * @param   u32NewValue     The value being written.
 *
 * @remarks The caller should not hold the device lock, unless it also holds
 *          the TM lock.
 */
static int hpetTimerRegWrite32(HPET *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t u32NewValue)
{
    Assert(!PDMCritSectIsOwner(&pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));

    if (   iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities)
        || iTimerNo >= RT_ELEMENTS(pThis->aTimers) )    /* Parfait - see above. */
    {
        static unsigned s_cOccurences = 0;
        if (s_cOccurences++ < 10)
            LogRel(("HPET: using timer above configured range: %d\n", iTimerNo));
        return VINF_SUCCESS;
    }
    HPETTIMER *pHpetTimer = &pThis->aTimers[iTimerNo];

    switch (iTimerReg)
    {
        case HPET_TN_CFG:
        {
            DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE);
            uint64_t    u64Mask = HPET_TN_CFG_WRITE_MASK;

            Log(("write HPET_TN_CFG: %d: %x\n", iTimerNo, u32NewValue));
            if (pHpetTimer->u64Config & HPET_TN_PERIODIC_CAP)
                u64Mask |= HPET_TN_PERIODIC;

            if (pHpetTimer->u64Config & HPET_TN_SIZE_CAP)
                u64Mask |= HPET_TN_32BIT;
            else
                u32NewValue &= ~HPET_TN_32BIT;

            if (u32NewValue & HPET_TN_32BIT)
            {
                Log(("setting timer %d to 32-bit mode\n", iTimerNo));
                pHpetTimer->u64Cmp    = (uint32_t)pHpetTimer->u64Cmp;
                pHpetTimer->u64Period = (uint32_t)pHpetTimer->u64Period;
            }
            if ((u32NewValue & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
            {
                static unsigned s_cOccurences = 0;
                if (s_cOccurences++ < 10)
                    LogRel(("level-triggered config not yet supported\n"));
                AssertFailed();
            }

            /* We only care about lower 32-bits so far */
            pHpetTimer->u64Config = hpetUpdateMasked(u32NewValue, pHpetTimer->u64Config, u64Mask);
            DEVHPET_UNLOCK(pThis);
            break;
        }

        case HPET_TN_CFG + 4: /* Interrupt capabilities - read only. */
        {
            Log(("write HPET_TN_CFG + 4, useless\n"));
            break;
        }

        case HPET_TN_CMP: /* lower bits of comparator register */
        {
            DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE);
            Log(("write HPET_TN_CMP on %d: %#x\n", iTimerNo, u32NewValue));

            if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
                pHpetTimer->u64Period = RT_MAKE_U64(u32NewValue, RT_HI_U32(pHpetTimer->u64Period));
            pHpetTimer->u64Cmp     = RT_MAKE_U64(u32NewValue, RT_HI_U32(pHpetTimer->u64Cmp));
            pHpetTimer->u64Config &= ~HPET_TN_SETVAL;
            Log2(("after HPET_TN_CMP cmp=%#llx per=%#llx\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period));

            if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
                hpetProgramTimer(pHpetTimer);
            DEVHPET_UNLOCK_BOTH(pThis);
            break;
        }

        case HPET_TN_CMP + 4: /* upper bits of comparator register */
        {
            DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE);
            Log(("write HPET_TN_CMP + 4 on %d: %#x\n", iTimerNo, u32NewValue));
            if (!hpet32bitTimer(pHpetTimer))
            {
                if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
                    pHpetTimer->u64Period = RT_MAKE_U64(RT_LO_U32(pHpetTimer->u64Period), u32NewValue);
                pHpetTimer->u64Cmp = RT_MAKE_U64(RT_LO_U32(pHpetTimer->u64Cmp), u32NewValue);

                Log2(("after HPET_TN_CMP+4 cmp=%llx per=%llx tmr=%d\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period, iTimerNo));

                pHpetTimer->u64Config &= ~HPET_TN_SETVAL;

                if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
                    hpetProgramTimer(pHpetTimer);
            }
            DEVHPET_UNLOCK_BOTH(pThis);
            break;
        }

        case HPET_TN_ROUTE:
        {
            Log(("write HPET_TN_ROUTE\n"));
            break;
        }

        case HPET_TN_ROUTE + 4:
        {
            Log(("write HPET_TN_ROUTE + 4\n"));
            break;
        }

        default:
        {
            static unsigned s_cOccurences = 0;
            if (s_cOccurences++ < 10)
                LogRel(("invalid timer register write: %d\n", iTimerReg));
            break;
        }
    }

    return VINF_SUCCESS;
}