Ejemplo n.º 1
0
bool
device_node::_AlwaysRegisterDynamic()
{
	uint16 type = 0;
	uint16 subType = 0;
	get_attr_uint16(this, B_DEVICE_TYPE, &type, false);
	get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false);

	return type == PCI_serial_bus || type == PCI_bridge || type == 0;
		// TODO: we may want to be a bit more specific in the future
}
Ejemplo n.º 2
0
status_t
device_node::Probe(const char* devicePath, uint32 updateCycle)
{
	if ((fFlags & NODE_FLAG_DEVICE_REMOVED) != 0
		|| updateCycle == fLastUpdateCycle)
		return B_OK;

	status_t status = InitDriver();
	if (status < B_OK)
		return status;

	MethodDeleter<device_node, bool> uninit(this,
		&device_node::UninitDriver);

	if ((fFlags & B_FIND_CHILD_ON_DEMAND) != 0) {
		bool matches = false;
		uint16 type = 0;
		uint16 subType = 0;
		if (get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) == B_OK
			&& get_attr_uint16(this, B_DEVICE_TYPE, &type, false) == B_OK) {
			// Check if this node matches the device path
			// TODO: maybe make this extendible via settings file?
			if (!strcmp(devicePath, "disk")) {
				matches = type == PCI_mass_storage;
			} else if (!strcmp(devicePath, "audio")) {
				matches = type == PCI_multimedia
					&& (subType == PCI_audio || subType == PCI_hd_audio);
			} else if (!strcmp(devicePath, "net")) {
				matches = type == PCI_network;
			} else if (!strcmp(devicePath, "graphics")) {
				matches = type == PCI_display;
			} else if (!strcmp(devicePath, "video")) {
				matches = type == PCI_multimedia && subType == PCI_video;
			}
		} else {
			// This driver does not support types, but still wants to its
			// children explored on demand only.
			matches = true;
			sGenericContextPath = devicePath;
		}

		if (matches) {
			fLastUpdateCycle = updateCycle;
				// This node will be probed in this update cycle

			status = _Probe();

			sGenericContextPath = NULL;
			return status;
		}

		return B_OK;
	}

	NodeList::Iterator iterator = fChildren.GetIterator();
	while (iterator.HasNext()) {
		device_node* child = iterator.Next();

		status = child->Probe(devicePath, updateCycle);
		if (status != B_OK)
			return status;
	}

	return B_OK;
}
Ejemplo n.º 3
0
status_t
device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
{
	Stack<KPath*>* stack = NULL;

	if (cookie == NULL) {
		// find all paths and add them
		stack = new(std::nothrow) Stack<KPath*>();
		if (stack == NULL)
			return B_NO_MEMORY;

		StackDeleter<KPath*> stackDeleter(stack);

		bool generic = false;
		uint16 type = 0;
		uint16 subType = 0;
		uint16 interface = 0;
		if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) != B_OK
			|| get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false)
					!= B_OK)
			generic = true;

		get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false);

		// TODO: maybe make this extendible via settings file?
		switch (type) {
			case PCI_mass_storage:
				switch (subType) {
					case PCI_scsi:
						_AddPath(*stack, "busses", "scsi");
						_AddPath(*stack, "busses", "virtio");
						break;
					case PCI_ide:
						_AddPath(*stack, "busses", "ata");
						_AddPath(*stack, "busses", "ide");
						break;
					case PCI_sata:
						// TODO: check for ahci interface
						_AddPath(*stack, "busses", "scsi");
						_AddPath(*stack, "busses", "ata");
						_AddPath(*stack, "busses", "ide");
						break;
					default:
						_AddPath(*stack, "busses");
						break;
				}
				break;
			case PCI_serial_bus:
				switch (subType) {
					case PCI_firewire:
						_AddPath(*stack, "busses", "firewire");
						break;
					case PCI_usb:
						_AddPath(*stack, "busses", "usb");
						break;
					default:
						_AddPath(*stack, "busses");
						break;
				}
				break;
			case PCI_network:
				_AddPath(*stack, "drivers", "net");
				_AddPath(*stack, "busses", "virtio");
				break;
			case PCI_display:
				_AddPath(*stack, "drivers", "graphics");
				break;
			case PCI_multimedia:
				switch (subType) {
					case PCI_audio:
					case PCI_hd_audio:
						_AddPath(*stack, "drivers", "audio");
						break;
					case PCI_video:
						_AddPath(*stack, "drivers", "video");
						break;
					default:
						_AddPath(*stack, "drivers");
						break;
				}
				break;
			default:
				if (sRootNode == this) {
					_AddPath(*stack, "busses/pci");
					_AddPath(*stack, "bus_managers");
				} else if (!generic) {
					_AddPath(*stack, "busses", "virtio");
					_AddPath(*stack, "drivers");
				} else {
					// For generic drivers, we only allow busses when the
					// request is more specified
					if (sGenericContextPath != NULL
						&& (!strcmp(sGenericContextPath, "disk")
							|| !strcmp(sGenericContextPath, "ports")
							|| !strcmp(sGenericContextPath, "bus"))) {
						_AddPath(*stack, "busses");
					}
					_AddPath(*stack, "drivers", sGenericContextPath);
					_AddPath(*stack, "busses/scsi");
					_AddPath(*stack, "busses/random");
				}
				break;
		}

		stackDeleter.Detach();

		cookie = (void*)stack;
	} else
		stack = static_cast<Stack<KPath*>*>(cookie);

	KPath* path;
	if (stack->Pop(&path)) {
		_path.Adopt(*path);
		delete path;
		return B_OK;
	}

	delete stack;
	return B_ENTRY_NOT_FOUND;
}
Ejemplo n.º 4
0
static int execute_query(parser_context *p_context, const char **attr)
{
    const char *type = 0;

    int ret = get_attr_str(attr, "type", &type);

    if(CPI_FAILED(ret)) { return ret; }

    /*! handle PIDX query */
    if(strncmp(type, "pidx", strlen("pidx")) == 0)
    {
        uint16_t key_id = 0;

        /*! retrieve key_id */
        {
            ret = get_attr_uint16(attr, "key_id", &key_id);

            if(CPI_FAILED(ret)) { return ret; }
        }

        ret = cpi_get_putative_id(p_context->p_cpi, key_id, p_context->p_cpi->tmp_buff_xml);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            output_condition_success_beg(p_context, type);
            strncat(p_context->out_xml_str, p_context->p_cpi->tmp_buff_xml, max_size);
            output_condition_success_end(p_context);
        }
    }
    /*! handle PKEY query */
    else if(strncmp(type, "pkey", strlen("pkey")) == 0)
    {
        uint16_t key_id = 0;

        /*! retrieve key_id */
        {
            ret = get_attr_uint16(attr, "key_id", &key_id);

            if(CPI_FAILED(ret)) { return ret; }
        }

        ret = cpi_get_public_key(p_context->p_cpi, key_id, p_context->p_cpi->tmp_buff_xml);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            output_condition_success_beg(p_context, type);
            strncat(p_context->out_xml_str, "\n", max_size);
            strncat(p_context->out_xml_str, p_context->p_cpi->tmp_buff_xml, max_size);
            strncat(p_context->out_xml_str, "    ", max_size);
            output_condition_success_end(p_context);
        }
    }
    /*! handle VERS query */
    else if(strncmp(type, "vers", strlen("vers")) == 0)
    {
        uint16_t major = 0, minor = 0, fix = 0;

        ret = cpi_get_version_number(p_context->p_cpi, &major, &minor, &fix);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            /*! generate version string major.minor.fix (e.g. 4.2.0) */
            sprintf(p_context->p_cpi->tmp_buff_xml, "%d.%d.%d", major, minor, fix);

            output_condition_success_beg(p_context, type);
            strncat(p_context->out_xml_str, p_context->p_cpi->tmp_buff_xml, max_size);
            output_condition_success_end(p_context);
        }
    }
    /*! handle TIME query */
    else if(strncmp(type, "time", strlen("time")) == 0)
    {
        uint32_t cur_time = 0;

        ret = cpi_get_current_time(p_context->p_cpi, &cur_time);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            /*! convert time to string format */
            sprintf(p_context->p_cpi->tmp_buff_xml, "%u", cur_time);

            output_condition_success_beg(p_context, type);
            strncat(p_context->out_xml_str, p_context->p_cpi->tmp_buff_xml, max_size);
            output_condition_success_end(p_context);
        }
    }
    /*! handle CKEY query */
    else if(strncmp(type, "ckey", strlen("ckey")) == 0)
    {
        uint32_t cur_oki = 0;

        ret = cpi_get_owner_key_index(p_context->p_cpi, &cur_oki);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            /*! convert owner key to string format */
            sprintf(p_context->p_cpi->tmp_buff_xml, "%u", cur_oki);

            output_condition_success_beg(p_context, type);
            strncat(p_context->out_xml_str, p_context->p_cpi->tmp_buff_xml, max_size);
            output_condition_success_end(p_context);
        }
    }
    /*! handle SNUM query */
    else if(strncmp(type, "snum", strlen("snum")) == 0)
    {
        uint8_t serial_number[CPI_SERIAL_NUMBER_SIZE] = { 0 };

        ret = cpi_get_serial_number(p_context->p_cpi, serial_number);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            /*! blank out temporary buffer */
            strcpy(p_context->p_cpi->tmp_buff_xml, "");

            /*! convert serial number to string format */
            {
                char buff[8];

                int v;
                for(v=0;v<CPI_SERIAL_NUMBER_SIZE;v++)
                {
                    sprintf(buff, "%.02X", (uint32_t)serial_number[v]);
                    strncat(p_context->p_cpi->tmp_buff_xml, buff, max_size);
                }
            }

            output_condition_success_beg(p_context, type);
            strncat(p_context->out_xml_str, p_context->p_cpi->tmp_buff_xml, max_size);
            output_condition_success_end(p_context);
        }
    }
    /*! handle HWVR query */
    else if(strncmp(type, "hwvr", strlen("hwvr")) == 0)
    {
        uint8_t hardware_version[CPI_HARDWARE_VERSION_SIZE] = { 0 };

        ret = cpi_get_hardware_version_data(p_context->p_cpi, hardware_version);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            /*! blank out temporary buffer */
            strcpy(p_context->p_cpi->tmp_buff_xml, "");

            /*! convert serial number to string format */
            {
                char buff[8];

                int v;
                for(v=0;v<CPI_HARDWARE_VERSION_SIZE;v++)
                {
                    sprintf(buff, "%.02X", (uint32_t)hardware_version[v]);
                    strncat(p_context->p_cpi->tmp_buff_xml, buff, max_size);
                }
            }

            output_condition_success_beg(p_context, type);
            strncat(p_context->out_xml_str, p_context->p_cpi->tmp_buff_xml, max_size);
            output_condition_success_end(p_context);
        }
    }
    /*! handle CHAL query */
    else if(strncmp(type, "chal", strlen("chal")) == 0)
    {
        uint16_t key_id = 0;
        uint8_t rand_data[CPI_RNDX_SIZE] = { 0 };

        /*! retrieve key_id */
        {
            ret = get_attr_uint16(attr, "key_id", &key_id);

            if(CPI_FAILED(ret)) { return ret; }
        }

        /*! parse random data input */
        {
            const char *rand_data_str = 0;

            ret = get_attr_str(attr, "rand_data", (char const **)&rand_data_str);

            if(CPI_FAILED(ret)) { return ret; }

            /*! handle invalid # of characters */
            if(strlen(rand_data_str) < (CPI_RNDX_SIZE*2)) { return CPI_FAIL; }

            int v;
            for(v=0;v<CPI_RNDX_SIZE;v++)
            {
                uint32_t cur_val = 0;

                ret = sscanf(&rand_data_str[v*2], "%02X", &cur_val);

                if(ret != 1) { return CPI_FAIL; }

                rand_data[v] = (uint8_t)cur_val;
            }
        }

        uint8_t *result1 = (uint8_t*)&p_context->p_cpi->tmp_buff_xml[0];
        uint8_t *result2 = (uint8_t*)&p_context->p_cpi->tmp_buff_xml[CPI_RESULT1_SIZE];
        uint8_t *result3 = (uint8_t*)&p_context->p_cpi->tmp_buff_xml[CPI_RESULT1_SIZE + CPI_RESULT2_SIZE];

        /*! clear result buffers */
        memset(result1, 0, CPI_RESULT1_SIZE);
        memset(result2, 0, CPI_RESULT2_SIZE);
        memset(result3, 0, CPI_RESULT3_SIZE);

        ret = cpi_issue_challenge(p_context->p_cpi, key_id, rand_data, result1, result2, result3);

        if(CPI_FAILED(ret))
        {
            output_condition_failure(p_context, type, ret);
        }
        else
        {
            output_condition_success_beg(p_context, type);

            strncat(p_context->out_xml_str, "\n", max_size);
            strncat(p_context->out_xml_str, "      <enc_owner_key>", max_size);

            /*! convert result1 to string format */
            {
                char buff[8];

                int v;
                for(v=0;v<CPI_RESULT1_SIZE;v++)
                {
                    sprintf(buff, "%.02X", (uint32_t)result1[v]);
                    strncat(p_context->out_xml_str, buff, max_size);

                    if(v == (CPI_RESULT1_ENC_OK_SIZE-1)) 
                    { 
                        strncat(p_context->out_xml_str, "</enc_owner_key>\n", max_size);
                        strncat(p_context->out_xml_str, "      <rand_data>", max_size);
                    }
                    else if(v == (CPI_RESULT1_ENC_OK_SIZE+CPI_RESULT1_RAND_SIZE-1))
                    {
                        strncat(p_context->out_xml_str, "</rand_data>\n", max_size);
                        strncat(p_context->out_xml_str, "      <vers>", max_size);
                    }
                    else if(v == (CPI_RESULT1_SIZE-1))
                    {
                        strncat(p_context->out_xml_str, "</vers>\n", max_size);
                    }
                }
            }

            strncat(p_context->out_xml_str, "      <signature>", max_size);

            /*! convert result2 to string format */
            {
                char buff[8];

                int v;
                for(v=0;v<CPI_RESULT2_SIZE;v++)
                {
                    sprintf(buff, "%.02X", (uint32_t)result2[v]);
                    strncat(p_context->out_xml_str, buff, max_size);
                }
            }
#if defined(CNPLATFORM_falconwing)
	    {
                char buff[8];

                int v;
                for(v=0;v<CPI_RESULT3_SIZE;v++)
                {
                    sprintf(buff, "%.02X", (uint32_t)result3[v]);
                    strncat(p_context->out_xml_str, buff, max_size);
                }
	    }
#endif

            strncat(p_context->out_xml_str, "</signature>\n", max_size);
            strncat(p_context->out_xml_str, "    ", max_size);

            output_condition_success_end(p_context);
        }
    }
    /*! handle unknown query */
    else
    {
        strncat(p_context->out_xml_str, "    <response result=\"failure\">Unknown \"type\" value</response>\n", max_size);
    }

    return CPI_OK;
}