Пример #1
0
void bu_hci::enque_acl(uint16_t handle, uint16_t cid, const sdata& sd)
{
    TRACE("::"<<__FUNCTION__);

    bybuff   aclbuf;
    uint16_t hf = (handle | (ACL_START_NO_FLUSH << 12));

#ifdef DEBUG
    //bybuff tr(sd.data, sd.len);
    //TRACE("toQ: handle:" << int(handle) << ", cid: " << int(cid));
    //TRACE("toQ: [" <<int(tr.length())<<"]" << tr.to_string());
#endif // DEBUG

    aclbuf << uint16_t(sd.len);
    aclbuf << uint16_t(cid);
    aclbuf.append(sd.data, sd.len);
    int mtu = int(this->_aclMtu);
    int len = int(aclbuf.length());
    int accum = 0;
    const uint8_t* paclbuff = aclbuf.buffer();

    while(len > 0)
    {
        AclChunk a;
        int      tocpy = std::min(mtu, len);
        a.acl.aclpkt  = uint8_t(HCI_ACLDATA_PKT);
        a.acl.aclhndl = btohs((uint16_t(hf)));
        a.acl.length  = btohs((uint16_t(tocpy)));
        hf |= (ACL_CONT << 12);
        a.aclsz  = 5 + tocpy;
        ::memcpy(a.acl.buff, paclbuff + accum, tocpy);
        accum += tocpy;
        len -= tocpy;
        std::deque<AclChunk>& r = _aclOut[handle];
        r.push_back(a);
      //  TRACE("Adding hander " << int(handle));
    }

   // TRACE("\nin Q: [" <<int(aclbuf.length())<<"]" << aclbuf.to_string());
   // TRACE("Queue: " << _aclOut.size() << " of "<<_aclOut[handle].size() << " chunks");
    flush_acl();
}
Пример #2
0
int bu_hci::on_sock_data(uint8_t code, const sdata& buffer) //received
{
    uint8_t  eventType = buffer.data[0];
    uint16_t blen = buffer.len;
    std::string scase="NOT HANDLED ";
    bybuff  trace(buffer.data, buffer.len);
    TRACE("{-->["<< int(buffer.len) <<"]"<< trace.to_string());

    if (HCI_EVENT_PKT == eventType)
    {
		uint8_t  subEventType = buffer.data[1];
        //_TRACE("    Event:" << int(eventType) << ", subevent:" << int(subEventType));

        switch(subEventType)
        {
            case EVT_DISCONN_COMPLETE:
                scase="EVT_DISCONN_COMPLETE";
                {
                    evt_disconn_complete* pdc = (evt_disconn_complete*)(buffer.data+4);
                    pdc->handle = htobs(pdc->handle);
                    memcpy(&_dcached, pdc, sizeof(_dcached));
#ifdef ACL_MTU_FRAG
                    flush_acl();
#endif //ACL_MTU_FRAG
                    _clear();
                    _pev->on_disconnect(pdc);
                    _connected=false;
                }
                break;
            case EVT_ENCRYPT_CHANGE:
                scase="EVT_ENCRYPT_CHANGE";
                {
                    evt_encrypt_change* pec = (evt_encrypt_change*)(buffer.data+4);
                    pec->handle=htobs(pec->handle);
                    _pev->on_encrypt_chnage(pec);
                }
                break;
            case EVT_CMD_COMPLETE:
                scase="       [EVT_CMD_COMPLETE]";
                {
                    no_evt_cmd_complete* necc = (no_evt_cmd_complete*)(buffer.data+3);
                    necc->cmd=htobs(necc->cmd);
                    this->_oncmd_complette(necc);
                }
                break;
            case EVT_LE_META_EVENT:
                scase="EVT_LE_META_EVENT";
                {
                    no_evt_le_meta_event* pev = (no_evt_le_meta_event*)(buffer.data+3);
                    this->_onmeta(pev);
                }
                break;
            case EVT_CONN_REQUEST:
                scase="EVT_CONN_REQUEST";
                {
                    evt_conn_request* preq= (evt_conn_request*)(buffer.data+4);
                    bdaddr_t dest;
                    baswap(&dest, &preq->bdaddr);
                    memcpy(&preq->bdaddr,&dest,sizeof(dest));
                }
                break;
            case  EVT_CMD_STATUS: //OCF_AUTH_REQUESTED
                scase="EVT_CMD_STATUS";
                {
                    evt_cmd_status* pevs = (evt_cmd_status*)(buffer.data+4);
					pevs->opcode = htobs(pevs->opcode);
					uint16_t ogf = CMD_OPCODE_OGF(pevs->opcode);
					uint16_t ocf = CMD_OPCODE_OCF(pevs->opcode);

                    TRACE("CMD_STATUS status:" <<int(pevs->status)<<" ncmd:" <<
												 int(pevs->ncmd) << " opcode(C/G):" <<
												 std::hex<<int(ocf) <<"/"<<int(ogf) << std::dec);
					if(ocf == OCF_EXIT_PERIODIC_INQUIRY)
					{
						//send_cmd(OCF_INQUIRY_CANCEL, OGF_LINK_CTL,0,0);
					}

                }
                break;
            case EVT_REMOTE_NAME_REQ_COMPLETE:
                scase="EVT_REMOTE_NAME_REQ_COMPLETE";
                {
                    evt_remote_name_req_complete* pnc = (evt_remote_name_req_complete*)(buffer.data+4);
                    TRACE("remote name: " << pnc->name);
                }
                break;
#ifdef ACL_MTU_FRAG
        case EVT_NUM_COMP_PKTS:
                scase="EVT_NUM_COMP_PKTS";
                {
                    uint8_t	nhandles = uint8_t(buffer.data[3]);
                   // TRACE("GOT number of completted acl packets:" << int(nhandles));
                    for(uint8_t h=0; h<nhandles; h++)
                    {
                        no_acl_handler_packet* pconfirm = (no_acl_handler_packet*)(buffer.data + 4 + (h*4));
                        pconfirm->handler = htobs(pconfirm->handler);
                        pconfirm->packet = htobs(pconfirm->packet);

                      //  TRACE("GOT Pending handler:" << int(pconfirm->handler) << ", " << int(pconfirm->packet));

                        const auto& ah = _aclPending.find(pconfirm->handler);
                        if(ah == this->_aclPending.end())
                        {
                           // TRACE("HANDLER "<<  int(pconfirm->handler)  <<" NOT FOUND");
                            continue;
                        }
                        else
                        {
                            ah->second -= pconfirm->packet;
                            if(ah->second <= 0)
                            {
                             //   TRACE("DELETE ALL HANDLER packets:" <<",["<<int(pconfirm->handler) <<"]" << int(ah->second));
                                _erase_AclOut(ah->first);
                            }
                        }
                    }
                    this->flush_acl();
        }
        break;
#endif //ACL_MTU_FRAG
            default:
                break;
        }//switch
    }

    else if (HCI_ACLDATA_PKT == eventType)
    {
        uint16_t  val =  oa2t<uint16_t>(buffer.data,1);
        uint16_t flags =  acl_flags(val);
        uint16_t handle = acl_handle(val);

        if(ACL_START_NO_FLUSH == flags)
        {
            //_clear_aclInQueue();  TODO
            scase="ACL_START_NO_FLUSH";
            flags = ACL_START;
        }
        if (ACL_START == flags)
        {
            uint16_t cid  = oa2t<uint16_t>(buffer.data,7);
            uint16_t expectedlen = oa2t<uint16_t>(buffer.data,5);

			uint16_t chunklen = blen-9;
			sdata sd;
			scase="ACL_START";
			sd.len = expectedlen;
			sd.data = buffer.data + 9;
			if (expectedlen == chunklen)
			{
				_pev->on_acl_packet(handle,cid, sd);
			}
			else
			{
                /// assert(_aclIn.find(handle) == _aclIn.end());
				//accumulate data bt handler
                if(_aclIn.find(handle) == _aclIn.end())
				{
					no_acl_start_len_dynamic* pd = new(no_acl_start_len_dynamic);
					pd->cit = (cid);
					pd->len = (chunklen);
					pd->expectedlen = (expectedlen);
					pd->byarr.insert(pd->byarr.end(), sd.data, sd.data + sd.len);
                    _aclIn[handle] = pd;
				}
				else
				{
                    _TRACE("ERROR AHNDLER NOT FOUND ....!. \n" << handle);
				}
			}

        }
        else if (ACL_CONT == flags)
        {
            /// keep accumulating, or discard
            uint16_t chunklen = blen-9;
            sdata sd;

            scase="ACL_CONT";

            auto el = _aclIn.find(handle);
            if (el == _aclIn.end())
                return true;

            no_acl_start_len_dynamic* pd = el->second;
            pd->len += chunklen;
            pd->byarr.insert(pd->byarr.end(), sd.data, sd.data + sd.len);
            //assert(pd->expectedlen == expectedlen);

            if(pd->expectedlen == pd->len )
            {
                sd.len = pd->len;
                sd.data = &pd->byarr[0];
                _pev->on_acl_packet(handle, pd->cit, sd);
                delete pd;
                _aclIn.erase(handle);
            }
        }
        else
        {
            _TRACE("!!! HCI_ACLDATA_PKT  unknown flag: " << std::hex << int(flags) << std::dec);
        }
    }
    else{
       _TRACE("!!!  NO KNOWN on_sock_data EVENTTYPE " << std::hex << int(eventType) << std::dec );
    }
    //TRACE("HCI: " << scase << "    }");
    return true;
}
int devnode_acl(const char *path,
                bool flush,
                bool del, uid_t old_uid,
                bool add, uid_t new_uid) {

    acl_t acl;
    int r = 0;
    bool changed = false;

    assert(path);

    acl = acl_get_file(path, ACL_TYPE_ACCESS);
    if (!acl)
        return -errno;

    if (flush) {

        r = flush_acl(acl);
        if (r < 0)
            goto finish;
        if (r > 0)
            changed = true;

    } else if (del && old_uid > 0) {
        acl_entry_t entry;

        r = acl_find_uid(acl, old_uid, &entry);
        if (r < 0)
            goto finish;

        if (r > 0) {
            if (acl_delete_entry(acl, entry) < 0) {
                r = -errno;
                goto finish;
            }

            changed = true;
        }
    }

    if (add && new_uid > 0) {
        acl_entry_t entry;
        acl_permset_t permset;
        int rd, wt;

        r = acl_find_uid(acl, new_uid, &entry);
        if (r < 0)
            goto finish;

        if (r == 0) {
            if (acl_create_entry(&acl, &entry) < 0) {
                r = -errno;
                goto finish;
            }

            if (acl_set_tag_type(entry, ACL_USER) < 0 ||
                    acl_set_qualifier(entry, &new_uid) < 0) {
                r = -errno;
                goto finish;
            }
        }

        if (acl_get_permset(entry, &permset) < 0) {
            r = -errno;
            goto finish;
        }

        rd = acl_get_perm(permset, ACL_READ);
        if (rd < 0) {
            r = -errno;
            goto finish;
        }

        wt = acl_get_perm(permset, ACL_WRITE);
        if (wt < 0) {
            r = -errno;
            goto finish;
        }

        if (!rd || !wt) {

            if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0) {
                r = -errno;
                goto finish;
            }

            changed = true;
        }
    }

    if (!changed)
        goto finish;

    if (acl_calc_mask(&acl) < 0) {
        r = -errno;
        goto finish;
    }

    if (acl_set_file(path, ACL_TYPE_ACCESS, acl) < 0) {
        r = -errno;
        goto finish;
    }

    r = 0;

finish:
    acl_free(acl);

    return r;
}