Пример #1
0
void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
{
    GameClient &computer = *static_cast< GameClient * >(comp);
    MessageOut result;

    if (computer.status == CLIENT_LOGIN)
    {
        if (message.getId() != PGMSG_CONNECT)
            return;

        std::string magic_token = message.readString(MAGIC_TOKEN_LENGTH);
        computer.status = CLIENT_QUEUED; // Before the addPendingClient
        mTokenCollector.addPendingClient(magic_token, &computer);
        return;
    }
    else if (computer.status != CLIENT_CONNECTED)
    {
        return;
    }

    switch (message.getId())
    {
        case PGMSG_SAY:
        {
            std::string say = message.readString();
            if (say.empty()) break;

            if (say[0] == '@')
            {
                CommandHandler::handleCommand(computer.character, say);
                break;
            }
            GameState::sayAround(computer.character, say);
            std::string msg = computer.character->getName() + " said " + say;
            accountHandler->sendTransaction(computer.character->getDatabaseID(), TRANS_MSG_PUBLIC, msg);
        } break;

        case PGMSG_NPC_TALK:
        case PGMSG_NPC_TALK_NEXT:
        case PGMSG_NPC_SELECT:
        case PGMSG_NPC_NUMBER:
        case PGMSG_NPC_STRING:
        {
            int id = message.readShort();
            Actor *o = findActorNear(computer.character, id);
            if (!o || o->getType() != OBJECT_NPC)
            {
                sendError(comp, id, "Not close enough to NPC\n");
                break;
            }

            NPC *q = static_cast< NPC * >(o);
            if (message.getId() == PGMSG_NPC_SELECT)
            {
                q->select(computer.character, message.readByte());
            }
            else if (message.getId() == PGMSG_NPC_NUMBER)
            {
                q->integerReceived(computer.character, message.readLong());
            }
            else if (message.getId() == PGMSG_NPC_STRING)
            {
                q->stringReceived(computer.character, message.readString());
            }
            else
            {
                q->prompt(computer.character, message.getId() == PGMSG_NPC_TALK);
            }
        } break;

        case PGMSG_PICKUP:
        {
            int x = message.readShort();
            int y = message.readShort();
            Point ppos = computer.character->getPosition();

            // TODO: use a less arbitrary value.
            if (std::abs(x - ppos.x) + std::abs(y - ppos.y) < 48)
            {
                MapComposite *map = computer.character->getMap();
                Point ipos(x, y);
                for (FixedActorIterator i(map->getAroundPointIterator(ipos, 0)); i; ++i)
                {
                    Actor *o = *i;
                    Point opos = o->getPosition();
                    if (o->getType() == OBJECT_ITEM && opos.x == x && opos.y == y)
                    {
                        Item *item = static_cast< Item * >(o);
                        ItemClass *ic = item->getItemClass();
                        Inventory(computer.character)
                            .insert(ic->getDatabaseID(), item->getAmount());
                        GameState::remove(item);
                        // log transaction
                        std::stringstream str;
                        str << "User picked up item " << ic->getDatabaseID()
                            << " at " << opos.x << "x" << opos.y;
                        accountHandler->sendTransaction(computer.character->getDatabaseID(),
                            TRANS_ITEM_PICKUP, str.str());
                        break;
                    }
                }
            }
        } break;

        case PGMSG_USE_ITEM:
        {
            int slot = message.readByte();
            Inventory inv(computer.character);
            if (ItemClass *ic = ItemManager::getItem(inv.getItem(slot)))
            {
                if (ic->use(computer.character))
                {
                    inv.removeFromSlot(slot, 1);
                    // log transaction
                    std::stringstream str;
                    str << "User used item " << ic->getDatabaseID()
                        << " from slot " << slot;
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_ITEM_USED, str.str());
                }
            }
        } break;

        case PGMSG_DROP:
        {
            int slot = message.readByte();
            int amount = message.readByte();
            Inventory inv(computer.character);
            if (ItemClass *ic = ItemManager::getItem(inv.getItem(slot)))
            {
                int nb = inv.removeFromSlot(slot, amount);
                Item *item = new Item(ic, amount - nb);
                item->setMap(computer.character->getMap());
                item->setPosition(computer.character->getPosition());
                if (!GameState::insert(item))
                {
                    // The map is full. Put back into inventory.
                    inv.insert(ic->getDatabaseID(), amount - nb);
                    delete item;
                    break;
                }
                // log transaction
                Point pt = computer.character->getPosition();
                std::stringstream str;
                str << "User dropped item " << ic->getDatabaseID()
                    << " at " << pt.x << "x" << pt.y;
                accountHandler->sendTransaction(computer.character->getDatabaseID(),
                    TRANS_ITEM_DROP, str.str());
            }
        } break;

        case PGMSG_WALK:
        {
            handleWalk(&computer, message);
        } break;

        case PGMSG_EQUIP:
        {
            int slot = message.readByte();
            Inventory(computer.character).equip(slot);
        } break;

        case PGMSG_UNEQUIP:
        {
            int slot = message.readByte();
            if (slot >= 0 && slot < EQUIP_PROJECTILE_SLOT)
            {
                Inventory(computer.character).unequip(slot);
            }
        } break;

        case PGMSG_MOVE_ITEM:
        {
            int slot1 = message.readByte();
            int slot2 = message.readByte();
            int amount = message.readByte();
            Inventory(computer.character).move(slot1, slot2, amount);
            // log transaction
            std::stringstream str;
            str << "User moved item "
                << " from slot " << slot1 << " to slot " << slot2;
            accountHandler->sendTransaction(computer.character->getDatabaseID(),
                TRANS_ITEM_MOVE, str.str());
        } break;

        case PGMSG_ATTACK:
        {
            int id = message.readShort();
            LOG_DEBUG("Character " << computer.character->getPublicID()
                      << " attacked being " << id);

            Actor *o = findActorNear(computer.character, id);
            if (o && o->getType() != OBJECT_NPC)
            {
                Being *being = static_cast<Being*>(o);
                computer.character->setTarget(being);
                computer.character->setAction(Being::ATTACK);
            }
        } break;

        case PGMSG_USE_SPECIAL:
        {
            int specialID = message.readByte();
            LOG_DEBUG("Character " << computer.character->getPublicID()
                      << " tries to use his special attack "<<specialID);
            computer.character->useSpecial(specialID);
        }

        case PGMSG_ACTION_CHANGE:
        {
            Being::Action action = (Being::Action)message.readByte();
            Being::Action current = (Being::Action)computer.character->getAction();
            bool logActionChange = true;

            switch (action)
            {
                case Being::STAND:
                {
                    if (current == Being::SIT)
                    {
                        computer.character->setAction(Being::STAND);
                        logActionChange = false;
                    }
                } break;
                case Being::SIT:
                {
                    if (current == Being::STAND)
                    {
                        computer.character->setAction(Being::SIT);
                        logActionChange = false;
                    }
                } break;
                default:
                    break;
            }

            // Log the action change only when this is relevant.
            if (logActionChange)
            {
                // log transaction
                std::stringstream str;
                str << "User changed action from " << current
                    << " to " << action;
                accountHandler->sendTransaction(
                    computer.character->getDatabaseID(),
                    TRANS_ACTION_CHANGE, str.str());
            }

        } break;

        case PGMSG_DIRECTION_CHANGE:
        {
            computer.character->setDirection(message.readByte());
        } break;

        case PGMSG_DISCONNECT:
        {
            bool reconnectAccount = (bool) message.readByte();

            result.writeShort(GPMSG_DISCONNECT_RESPONSE);
            result.writeByte(ERRMSG_OK); // It is, when control reaches here

            if (reconnectAccount)
            {
                std::string magic_token(utils::getMagicToken());
                result.writeString(magic_token, MAGIC_TOKEN_LENGTH);
                // No accountserver data, the client should remember that
                accountHandler->playerReconnectAccount(
                                   computer.character->getDatabaseID(),
                                   magic_token);
            }
            // TODO: implement a delayed remove
            GameState::remove(computer.character);

            accountHandler->sendCharacterData(computer.character);

            // Done with the character
            computer.character->disconnected();
            delete computer.character;
            computer.character = NULL;
            computer.status = CLIENT_LOGIN;
        } break;

        case PGMSG_TRADE_REQUEST:
        {
            int id = message.readShort();

            if (Trade *t = computer.character->getTrading())
            {
                if (t->request(computer.character, id)) break;
            }

            Character *q = findCharacterNear(computer.character, id);
            if (!q || q->isBusy())
            {
                result.writeShort(GPMSG_TRADE_CANCEL);
                break;
            }

            new Trade(computer.character, q);

            // log transaction
            std::string str;
            str = "User requested trade with " + q->getName();
            accountHandler->sendTransaction(computer.character->getDatabaseID(),
                TRANS_TRADE_REQUEST, str);
        } break;

        case PGMSG_TRADE_CANCEL:
        case PGMSG_TRADE_AGREED:
        case PGMSG_TRADE_CONFIRM:
        case PGMSG_TRADE_ADD_ITEM:
        case PGMSG_TRADE_SET_MONEY:
        {
            std::stringstream str;
            Trade *t = computer.character->getTrading();
            if (!t) break;

            switch (message.getId())
            {
                case PGMSG_TRADE_CANCEL:
                    t->cancel();
                    break;
                case PGMSG_TRADE_CONFIRM:
                    t->confirm(computer.character);
                    break;
                case PGMSG_TRADE_AGREED:
                    t->agree(computer.character);
                    // log transaction
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_TRADE_END, "User finished trading");
                    break;
                case PGMSG_TRADE_SET_MONEY:
                {
                    int money = message.readLong();
                    t->setMoney(computer.character, money);
                    // log transaction
                    str << "User added " << money << " money to trade.";
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_TRADE_MONEY, str.str());
                } break;
                case PGMSG_TRADE_ADD_ITEM:
                {
                    int slot = message.readByte();
                    t->addItem(computer.character, slot, message.readByte());
                    // log transaction
                    str << "User add item from slot " << slot;
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_TRADE_ITEM, str.str());
                } break;
            }
        } break;

        case PGMSG_NPC_BUYSELL:
        {
            BuySell *t = computer.character->getBuySell();
            if (!t) break;
            int id = message.readShort();
            int amount = message.readShort();
            t->perform(id, amount);
        } break;

        case PGMSG_RAISE_ATTRIBUTE:
        {
            int attribute = message.readByte();
            AttribmodResponseCode retCode;
            retCode = computer.character->useCharacterPoint(attribute);
            result.writeShort(GPMSG_RAISE_ATTRIBUTE_RESPONSE);
            result.writeByte(retCode);
            result.writeByte(attribute);

            if (retCode == ATTRIBMOD_OK )
            {
                accountHandler->updateCharacterPoints(
                    computer.character->getDatabaseID(),
                    computer.character->getCharacterPoints(),
                    computer.character->getCorrectionPoints(),
                    attribute,
                    computer.character->getAttribute(attribute));

                // log transaction
                std::stringstream str;
                str << "User increased attribute " << attribute;
                accountHandler->sendTransaction(computer.character->getDatabaseID(),
                    TRANS_ATTR_INCREASE, str.str());
            }
        } break;

        case PGMSG_LOWER_ATTRIBUTE:
        {
            int attribute = message.readByte();
            AttribmodResponseCode retCode;
            retCode = computer.character->useCorrectionPoint(attribute);
            result.writeShort(GPMSG_LOWER_ATTRIBUTE_RESPONSE);
            result.writeByte(retCode);
            result.writeByte(attribute);

            if (retCode == ATTRIBMOD_OK )
            {
                accountHandler->updateCharacterPoints(
                    computer.character->getDatabaseID(),
                    computer.character->getCharacterPoints(),
                    computer.character->getCorrectionPoints(),
                    attribute,
                    computer.character->getAttribute(attribute));

                // log transaction
                std::stringstream str;
                str << "User decreased attribute " << attribute;
                accountHandler->sendTransaction(computer.character->getDatabaseID(),
                    TRANS_ATTR_DECREASE, str.str());
            }
        } break;

        case PGMSG_RESPAWN:
        {
            computer.character->respawn(); // plausibility check is done by character class
        } break;

        case PGMSG_NPC_POST_SEND:
        {
            handleSendPost(&computer, message);
        } break;

        default:
            LOG_WARN("Invalid message type");
            result.writeShort(XXMSG_INVALID);
            break;
    }

    if (result.getLength() > 0)
        computer.send(result);
}
Пример #2
0
/* Un-initialize the ssp module and initialize the SPIFI module */
static int lpcspifi_set_hw_mode(struct flash_bank *bank)
{
	struct target *target = bank->target;
	struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
	uint32_t ssp_base = lpcspifi_info->ssp_base;
	struct armv7m_algorithm armv7m_info;
	struct working_area *spifi_init_algorithm;
	struct reg_param reg_params[2];
	int retval = ERROR_OK;

	LOG_DEBUG("Uninitializing LPC43xx SSP");
	/* Turn off the SSP module */
	retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000);
	if (retval != ERROR_OK)
		return retval;

	/* see contrib/loaders/flash/lpcspifi_init.S for src */
	static const uint8_t spifi_init_code[] = {
		0x4f, 0xea, 0x00, 0x08, 0xa1, 0xb0, 0x00, 0xaf,
		0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
		0x4f, 0xf0, 0xf3, 0x02, 0xc3, 0xf8, 0x8c, 0x21,
		0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
		0x4f, 0xf4, 0xc0, 0x42, 0xc4, 0xf2, 0x08, 0x02,
		0x4f, 0xf4, 0xc0, 0x41, 0xc4, 0xf2, 0x08, 0x01,
		0x4f, 0xf4, 0xc0, 0x40, 0xc4, 0xf2, 0x08, 0x00,
		0x4f, 0xf0, 0xd3, 0x04, 0xc0, 0xf8, 0x9c, 0x41,
		0x20, 0x46, 0xc1, 0xf8, 0x98, 0x01, 0x01, 0x46,
		0xc2, 0xf8, 0x94, 0x11, 0xc3, 0xf8, 0x90, 0x11,
		0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
		0x4f, 0xf0, 0x13, 0x02, 0xc3, 0xf8, 0xa0, 0x21,
		0x40, 0xf2, 0x18, 0x13, 0xc1, 0xf2, 0x40, 0x03,
		0x1b, 0x68, 0x1c, 0x68, 0x40, 0xf2, 0xb4, 0x30,
		0xc1, 0xf2, 0x00, 0x00, 0x4f, 0xf0, 0x03, 0x01,
		0x4f, 0xf0, 0xc0, 0x02, 0x4f, 0xea, 0x08, 0x03,
		0xa0, 0x47, 0x00, 0xf0, 0x00, 0xb8, 0x00, 0xbe
	};

	armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
	armv7m_info.core_mode = ARM_MODE_THREAD;


	LOG_DEBUG("Allocating working area for SPIFI init algorithm");
	/* Get memory for spifi initialization algorithm */
	retval = target_alloc_working_area(target, sizeof(spifi_init_code)
		+ SPIFI_INIT_STACK_SIZE, &spifi_init_algorithm);
	if (retval != ERROR_OK) {
		LOG_ERROR("Insufficient working area to initialize SPIFI "\
			"module. You must allocate at least %zdB of working "\
			"area in order to use this driver.",
			sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE
		);

		return retval;
	}

	LOG_DEBUG("Writing algorithm to working area at 0x%08" PRIx32,
		spifi_init_algorithm->address);
	/* Write algorithm to working area */
	retval = target_write_buffer(target,
		spifi_init_algorithm->address,
		sizeof(spifi_init_code),
		spifi_init_code
	);

	if (retval != ERROR_OK) {
		target_free_working_area(target, spifi_init_algorithm);
		return retval;
	}

	init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);		/* spifi clk speed */
	/* the spifi_init() rom API makes use of the stack */
	init_reg_param(&reg_params[1], "sp", 32, PARAM_OUT);

	/* For now, the algorithm will set up the SPIFI module
	 * @ the IRC clock speed. In the future, it could be made
	 * a bit smarter to use other clock sources if the user has
	 * already configured them in order to speed up memory-
	 * mapped reads. */
	buf_set_u32(reg_params[0].value, 0, 32, 12);
	/* valid stack pointer */
	buf_set_u32(reg_params[1].value, 0, 32, (spifi_init_algorithm->address +
		sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE) & ~7UL);

	/* Run the algorithm */
	LOG_DEBUG("Running SPIFI init algorithm");
	retval = target_run_algorithm(target, 0 , NULL, 2, reg_params,
		spifi_init_algorithm->address,
		spifi_init_algorithm->address + sizeof(spifi_init_code) - 2,
		1000, &armv7m_info);

	if (retval != ERROR_OK)
		LOG_ERROR("Error executing SPIFI init algorithm");

	target_free_working_area(target, spifi_init_algorithm);

	destroy_reg_param(&reg_params[0]);
	destroy_reg_param(&reg_params[1]);

	return retval;
}
Пример #3
0
static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,
	uint32_t offset, uint32_t count)
{
	struct target *target = bank->target;
	struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
	uint32_t page_size, fifo_size;
	struct working_area *fifo;
	struct reg_param reg_params[5];
	struct armv7m_algorithm armv7m_info;
	struct working_area *write_algorithm;
	int sector;
	int retval = ERROR_OK;

	LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32,
		offset, count);

	if (target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if (offset + count > lpcspifi_info->dev->size_in_bytes) {
		LOG_WARNING("Writes past end of flash. Extra data discarded.");
		count = lpcspifi_info->dev->size_in_bytes - offset;
	}

	/* Check sector protection */
	for (sector = 0; sector < bank->num_sectors; sector++) {
		/* Start offset in or before this sector? */
		/* End offset in or behind this sector? */
		if ((offset <
				(bank->sectors[sector].offset + bank->sectors[sector].size))
			&& ((offset + count - 1) >= bank->sectors[sector].offset)
			&& bank->sectors[sector].is_protected) {
			LOG_ERROR("Flash sector %d protected", sector);
			return ERROR_FAIL;
		}
	}

	page_size = lpcspifi_info->dev->pagesize;

	retval = lpcspifi_set_hw_mode(bank);
	if (retval != ERROR_OK)
		return retval;

	/* see contrib/loaders/flash/lpcspifi_write.S for src */
	static const uint8_t lpcspifi_flash_write_code[] = {
		0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
		0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
		0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
		0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
		0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
		0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
		0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
		0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
		0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
		0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
		0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
		0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
		0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
		0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
		0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
		0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
		0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
		0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
		0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
		0x4f, 0xf0, 0x00, 0x0b, 0xa3, 0x44, 0x93, 0x45,
		0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6a, 0xf8,
		0x4f, 0xf0, 0x06, 0x09, 0x00, 0xf0, 0x53, 0xf8,
		0x00, 0xf0, 0x60, 0xf8, 0x00, 0xf0, 0x62, 0xf8,
		0x4f, 0xf0, 0x05, 0x09, 0x00, 0xf0, 0x4b, 0xf8,
		0x4f, 0xf0, 0x00, 0x09, 0x00, 0xf0, 0x47, 0xf8,
		0x00, 0xf0, 0x54, 0xf8, 0x19, 0xf0, 0x02, 0x0f,
		0x00, 0xf0, 0x5d, 0x80, 0x00, 0xf0, 0x52, 0xf8,
		0x4f, 0xf0, 0x02, 0x09, 0x00, 0xf0, 0x3b, 0xf8,
		0x4f, 0xea, 0x12, 0x49, 0x00, 0xf0, 0x37, 0xf8,
		0x4f, 0xea, 0x12, 0x29, 0x00, 0xf0, 0x33, 0xf8,
		0x4f, 0xea, 0x02, 0x09, 0x00, 0xf0, 0x2f, 0xf8,
		0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f,
		0x00, 0xf0, 0x47, 0x80, 0x47, 0x68, 0x47, 0x45,
		0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8, 0x01, 0x9b,
		0x00, 0xf0, 0x21, 0xf8, 0x8f, 0x42, 0x28, 0xbf,
		0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, 0x01, 0x3b,
		0xbb, 0xb3, 0x02, 0xf1, 0x01, 0x02, 0x93, 0x45,
		0x7f, 0xf4, 0xe6, 0xaf, 0x00, 0xf0, 0x22, 0xf8,
		0xa3, 0x44, 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xf0,
		0x05, 0x09, 0x00, 0xf0, 0x0c, 0xf8, 0x4f, 0xf0,
		0x00, 0x09, 0x00, 0xf0, 0x08, 0xf8, 0x00, 0xf0,
		0x15, 0xf8, 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4,
		0xf0, 0xaf, 0xff, 0xf7, 0xa7, 0xbf, 0x4f, 0xf4,
		0x40, 0x5a, 0xc4, 0xf2, 0x08, 0x0a, 0xca, 0xf8,
		0x08, 0x90, 0xda, 0xf8, 0x0c, 0x90, 0x19, 0xf0,
		0x10, 0x0f, 0x7f, 0xf4, 0xfa, 0xaf, 0xda, 0xf8,
		0x08, 0x90, 0x70, 0x47, 0x4f, 0xf0, 0xff, 0x08,
		0x00, 0xf0, 0x02, 0xb8, 0x4f, 0xf0, 0x00, 0x08,
		0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
		0xca, 0xf8, 0xab, 0x80, 0x70, 0x47, 0x00, 0x20,
		0x50, 0x60, 0xff, 0xf7, 0xef, 0xff, 0x30, 0x46,
		0x00, 0xbe, 0xff, 0xff
	};

	if (target_alloc_working_area(target, sizeof(lpcspifi_flash_write_code),
			&write_algorithm) != ERROR_OK) {
		LOG_ERROR("Insufficient working area. You must configure"\
			" a working area > %zdB in order to write to SPIFI flash.",
			sizeof(lpcspifi_flash_write_code));
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
	}

	retval = target_write_buffer(target, write_algorithm->address,
			sizeof(lpcspifi_flash_write_code),
			lpcspifi_flash_write_code);
	if (retval != ERROR_OK) {
		target_free_working_area(target, write_algorithm);
		return retval;
	}

	/* FIFO allocation */
	fifo_size = target_get_working_area_avail(target);

	if (fifo_size == 0) {
		/* if we already allocated the writing code but failed to get fifo
		 * space, free the algorithm */
		target_free_working_area(target, write_algorithm);

		LOG_ERROR("Insufficient working area. Please allocate at least"\
			" %zdB of working area to enable flash writes.",
			sizeof(lpcspifi_flash_write_code) + 1
		);

		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
	} else if (fifo_size < page_size)
		LOG_WARNING("Working area size is limited; flash writes may be"\
			" slow. Increase working area size to at least %zdB"\
			" to reduce write times.",
			(size_t)(sizeof(lpcspifi_flash_write_code) + page_size)
		);
	else if (fifo_size > 0x2000) /* Beyond this point, we start to get diminishing returns */
		fifo_size = 0x2000;

	if (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {
		target_free_working_area(target, write_algorithm);
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
	}

	armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
	armv7m_info.core_mode = ARM_MODE_THREAD;

	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);		/* buffer start, status (out) */
	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);		/* buffer end */
	init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);		/* target address */
	init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);		/* count (halfword-16bit) */
	init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);		/* page size */

	buf_set_u32(reg_params[0].value, 0, 32, fifo->address);
	buf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size);
	buf_set_u32(reg_params[2].value, 0, 32, offset);
	buf_set_u32(reg_params[3].value, 0, 32, count);
	buf_set_u32(reg_params[4].value, 0, 32, page_size);

	retval = target_run_flash_async_algorithm(target, buffer, count, 1,
			0, NULL,
			5, reg_params,
			fifo->address, fifo->size,
			write_algorithm->address, 0,
			&armv7m_info
	);

	if (retval != ERROR_OK)
		LOG_ERROR("Error executing flash write algorithm");

	target_free_working_area(target, fifo);
	target_free_working_area(target, write_algorithm);

	destroy_reg_param(&reg_params[0]);
	destroy_reg_param(&reg_params[1]);
	destroy_reg_param(&reg_params[2]);
	destroy_reg_param(&reg_params[3]);
	destroy_reg_param(&reg_params[4]);

	/* Switch to HW mode before return to prompt */
	retval = lpcspifi_set_hw_mode(bank);
	return retval;
}
Пример #4
0
static int stmsmi_probe(struct flash_bank *bank)
{
	struct target *target = bank->target;
	struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;
	uint32_t io_base;
	struct flash_sector *sectors;
	uint32_t id = 0; /* silence uninitialized warning */
	struct stmsmi_target *target_device;
	int retval;

	if (stmsmi_info->probed)
		free(bank->sectors);
	stmsmi_info->probed = 0;

	for (target_device=target_devices ; target_device->name ; ++target_device)
		if (target_device->tap_idcode == target->tap->idcode)
			break;
	if (!target_device->name)
	{
		LOG_ERROR("Device ID 0x%" PRIx32 " is not known as SMI capable",
				target->tap->idcode);
		return ERROR_FAIL;
	}

	switch (bank->base - target_device->smi_base)
	{
		case 0:
			stmsmi_info->bank_num = SMI_SEL_BANK0;
			break;
		case SMI_BANK_SIZE:
			stmsmi_info->bank_num = SMI_SEL_BANK1;
			break;
		case 2*SMI_BANK_SIZE:
			stmsmi_info->bank_num = SMI_SEL_BANK2;
			break;
		case 3*SMI_BANK_SIZE:
			stmsmi_info->bank_num = SMI_SEL_BANK3;
			break;
		default:
			LOG_ERROR("Invalid SMI base address 0x%" PRIx32, bank->base);
			return ERROR_FAIL;
	}
	io_base = target_device->io_base;
	stmsmi_info->io_base = io_base;

	LOG_DEBUG("Valid SMI on device %s at address 0x%" PRIx32,
		target_device->name, bank->base);

	/* read and decode flash ID; returns in SW mode */
	retval = read_flash_id(bank, &id);
	SMI_SET_HW_MODE();
	if (retval != ERROR_OK)
		return retval;

	stmsmi_info->dev = NULL;
	for (struct flash_device *p = flash_devices; p->name ; p++)
		if (p->device_id == id) {
			stmsmi_info->dev = p;
			break;
		}

	if (!stmsmi_info->dev)
	{
		LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
		return ERROR_FAIL;
	}

	LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
		stmsmi_info->dev->name, stmsmi_info->dev->device_id);

	/* Set correct size value */
	bank->size = stmsmi_info->dev->size_in_bytes;

	/* create and fill sectors array */
	bank->num_sectors =
		stmsmi_info->dev->size_in_bytes / stmsmi_info->dev->sectorsize;
	sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
	if (sectors == NULL)
	{
		LOG_ERROR("not enough memory");
		return ERROR_FAIL;
	}

	for (int sector = 0; sector < bank->num_sectors; sector++)
	{
		sectors[sector].offset = sector * stmsmi_info->dev->sectorsize;
		sectors[sector].size = stmsmi_info->dev->sectorsize;
		sectors[sector].is_erased = -1;
		sectors[sector].is_protected = 1;
	}

	bank->sectors = sectors;
	stmsmi_info->probed = 1;
	return ERROR_OK;
}
/**
 * A thread that actually handles the registration request of the GUI (internal
 * use only). See rm_register_account() for details.
 * @param args the account ID is stored here
 * @return empty
 */
void *registration_thread(void *args) {
	int accountId;				// current account
	int pos;					// position of account status information
	int rc;						// return code
	int counter;				// counter for registration expire
	int timeoutCtr;				// timeout counter for sipstack events
	struct account *acc;		// account data from account management
	char *from;					// SIP from field
	char *registrar;			// SIP registrar field

	// accountId is given:
	accountId = (int) args;

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "registration thread entered, "
			  "accountId: %d", accountId);

	// try to gain lock because we want exclusive responsibility for this
	// account and we need to use a new position for account status info:
	rc = pthread_mutex_lock(&accInfoLock);
	if (rc != 0) {
		// failed to gain lock, exit (fatal error)
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "mutex lock could not be"
				  "acquired, error: %d", rc);
		thread_terminated();
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "mutex lock acquired");

	// is another thread handling (un-)registration of this account?
	rc = find_acc_by_id(accountId, NULL);
	if (rc) {
		// account is blocked by another thread (impatient GUI user?)
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "account already in use");

		rc = go_show_user_event(accountId, "ERROR",
								"Error registering account",
								"Account is already in use.",
								"Either this account is already "
								"registered or it is currently tried to "
								"unregister this account.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// inform GUI and exit:
		leave_reg_thrd_with_error(-1, accountId, 0);
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "account is not in use");

	// try to find empty position to save account status information
	// (there has to be one position for every account of account information)
	pos = find_empty_acc_info();
	if (pos == -1) {
		// no position found (fatal error):
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "no empty position found");
		rc = go_show_user_event(accountId, "ERROR",
								"Error registering account",
								"Maximum number of active accounts "
								"exceeded.",
								"You have registered more accounts than "
								"are allowed by the Core configuration.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// inform GUI and exit:
		leave_reg_thrd_with_error(-1, accountId, 0);
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "position found: %d", pos);

	// if we set an account ID the array position is marked as used:
	accInfos[pos].accountId = accountId;
	accInfos[pos].isRegistered = 0;

	// get account data from account management:
	acc = am_get_account(accountId);
	if (!acc) {
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "account management did not "
				  "return matching account data.");

		rc = go_show_user_event(accountId, "ERROR",
								"Error registering account",
								"No such account available.",
								"Account management did not return "
								"matching account data.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// inform GUI and exit:
		leave_reg_thrd_with_error(pos, accountId, 0);
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "account management found matching "
			  "account data.");

	// check fields required for registration:
	if (!acc->domain || !acc->username || !acc->registrar) {
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX
				  "domain, username or registrar is missing");

		rc = go_show_user_event(accountId, "ERROR",
								"Error registering account",
								"Account information is invalid.",
								"Your account is missing either domain, "
								"user name or registrar. Please check "
								"your account information.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// inform GUI and exit:
		leave_reg_thrd_with_error(pos, accountId, 0);
		return NULL;
	}

	if (strcmp(acc->domain, "") == 0 || strcmp(acc->username, "") == 0
		|| strcmp(acc->registrar, "") == 0) {
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX
				  "domain, username or registrar is empty");

		rc = go_show_user_event(accountId, "ERROR",
								"Error registering account",
								"Account information is invalid.",
								"Your account is missing either domain, "
								"user name or registrar. Please check "
								"your account information.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// inform GUI and exit:
		leave_reg_thrd_with_error(pos, accountId, 0);
		return NULL;
	}
	// build SIP From and SIP Registrar:
	from = (char *) malloc(1024 * sizeof(char));
	registrar = (char *) malloc(1024 * sizeof(char));
	sprintf(from, "sip:%s@%s", acc->username, acc->domain);
	sprintf(registrar, "sip:%s", acc->registrar);

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "from: %s registrar: %s", from,
			  registrar);

	// now send initial REGISTER to registrar
	int regId = sipstack_send_register(from, registrar,
									   config.core.sipOutput.
									   registrarManager.expire);
	if (regId == -1) {
		// no valid registration ID returned because of an error
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "send register failed");

		rc = go_show_user_event(accountId, "ERROR",
								"Error registering account",
								"Sending registration message failed.",
								"Failed to send your registration "
								"request to the given registrar."
								"Please check whether your account "
								"data is correct and whether your "
								"internet connection is working "
								"correctly.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// free strings:
		free(from);
		free(registrar);

		// inform GUI and exit:
		leave_reg_thrd_with_error(pos, accountId, 0);
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "send register succeeded, "
			  "regId: %d", regId);

	accInfos[pos].regId = regId;
	accInfos[pos].waitingOnRegOK = 1;	// tell dispatcher which OK is expected

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "now waiting on OK");

	// marked account as "used"
	rc = pthread_mutex_unlock(&accInfoLock);
	if (rc != 0) {
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "releasing mutex lock "
				  "failed, error: %d", rc);

		// free strings:
		free(from);
		free(registrar);

		// inform GUI and exit:
		leave_reg_thrd_with_error(pos, accountId, 0);
		return NULL;
	}
	// now wait on response:
	timeoutCtr = 0;
	while (!accInfos[pos].eventArrived) {
		sched_yield();
		usleep(100000);			// 0.1 seconds
		timeoutCtr++;
		if (timeoutCtr ==
			config.core.sipOutput.registrarManager.timeout * 10) {
			break;
		}
	}
	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "done waiting");

	// clear event waiting flags:
	accInfos[pos].eventArrived = 0;
	accInfos[pos].waitingOnRegOK = 0;

	// free strings:
	if (from) {
		free(from);
	}
	if (registrar) {
		free(registrar);
	}
	// test if we did receive an OK (isRegistered is set by dispatcher):
	if (!accInfos[pos].isRegistered) {
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "registering failed");

		rc = go_show_user_event(accountId, "ERROR",
								"Error registering account",
								"Sending registration message failed.",
								"Failed to send your registration "
								"request to the given registrar."
								"Please check whether your account "
								"data is correct and whether your "
								"internet connection is working "
								"correctly.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// inform GUI and exit:
		leave_reg_thrd_with_error(pos, accountId, 1);
		return NULL;
	}
	// inform GUI that registration succeeded:
	rc = go_change_reg_status(accountId, 1);
	if (!rc) {
		// could not contact GUI (error):
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "GUI registration status update"
				  " failed");

		// inform GUI and exit (it is unlikely to succeed but try anyway):
		leave_reg_thrd_with_error(pos, accountId, 1);
		return NULL;
	}

	LOG_INFO(REGISTRAR_MGR_MSG_PREFIX "registration was successful for "
			 "account: %d", accountId);
	// **********************************************************************

	// now we are responsible for updating registration
	counter = 0;
	while (!accInfos[pos].doShutdown) {
		sleep(1);				// test every second for shutdown or imminent expire
		counter++;
		if (counter ==
			config.core.sipOutput.registrarManager.expire -
			config.core.sipOutput.registrarManager.preExpireRange) {

			// now expire is nearly reached, update registration:

			counter = 0;

			// tell dispatcher on which OK we are waiting for:
			accInfos[pos].waitingOnRefreshOK = 1;

			// send n-th REGISTER to registrar:
			rc = sipstack_send_update_register(regId,
											   config.core.sipOutput.
											   registrarManager.expire);
			if (rc == 0) {
				// send REGISTER failed
				LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "send update register"
						  " failed");
				rc = go_show_user_event(accountId, "ERROR",
										"Error refreshing account "
										"registration",
										"Sending automated registration "
										"message failed.",
										"Failed to send registration "
										"refresh to the given registrar. "
										"Please check whether your account "
										"data is correct and whether your "
										"internet connection is working "
										"correctly.");
				if (!rc) {
					LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX
							  "failed to inform the GUI");
				}
				// inform GUI and exit:
				leave_reg_thrd_with_error(pos, accountId, 1);
				return NULL;
			}

			LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "now waiting on OK");

			timeoutCtr = 0;
			// now wait on response:
			while (!accInfos[pos].eventArrived) {
				sched_yield();
				usleep(100000);	// 0.1 seconds
				timeoutCtr++;
				if (timeoutCtr ==
					config.core.sipOutput.registrarManager.timeout * 10) {
					break;
				}
			}
			LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "done waiting");

			// test if OK arrived:
			if (!accInfos[pos].isRefreshed) {
				LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX
						  "updating registration failed");
				rc = go_show_user_event(accountId, "ERROR",
										"Error refreshing account "
										"registration",
										"Sending automated registration "
										"message failed.",
										"Failed to send registration "
										"refresh to the given registrar. "
										"Please check whether your account "
										"data is correct and whether your "
										"internet connection is working "
										"correctly.");
				if (!rc) {
					LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX
							  "failed to inform the GUI");
				}
				// inform GUI and exit:
				leave_reg_thrd_with_error(pos, accountId, 1);
				return NULL;
			}
			// clear flags:
			accInfos[pos].isRefreshed = 0;
			accInfos[pos].eventArrived = 0;
			accInfos[pos].waitingOnRefreshOK = 0;

			LOG_INFO(REGISTRAR_MGR_MSG_PREFIX "registration updated for "
					 "account: %d", accountId);
		}
	}

	// if an unregister-thread requested quitting this thread we tell it that
	// we are done (no lock required because other thread is only reading):
	accInfos[pos].doShutdown = 0;
	accInfos[pos].isShutdown = 1;
	thread_terminated();
	return NULL;
}
Пример #6
0
static decode_state faad_decode(void) {
	size_t bytes_total;
	size_t bytes_wrap;
	NeAACDecFrameInfo info;
	s32_t *iptr;
	bool endstream;
	frames_t frames;

	LOCK_S;
	bytes_total = _buf_used(streambuf);
	bytes_wrap  = min(bytes_total, _buf_cont_read(streambuf));

	if (stream.state <= DISCONNECT && !bytes_total) {
		UNLOCK_S;
		return DECODE_COMPLETE;
	}

	if (a->consume) {
		u32_t consume = min(a->consume, bytes_wrap);
		LOG_DEBUG("consume: %u of %u", consume, a->consume);
		_buf_inc_readp(streambuf, consume);
		a->pos += consume;
		a->consume -= consume;
		UNLOCK_S;
		return DECODE_RUNNING;
	}

	if (decode.new_stream) {
		int found = 0;
		static unsigned char channels;
		static unsigned long samplerate;

		if (a->type == '2') {

			// adts stream - seek for header
			while (bytes_wrap >= 2 && (*(streambuf->readp) != 0xFF || (*(streambuf->readp + 1) & 0xF6) != 0xF0)) {
				_buf_inc_readp(streambuf, 1);
				bytes_total--;
				bytes_wrap--;
			}
			
			if (bytes_wrap >= 2) {
				long n = NEAAC(a, Init, a->hAac, streambuf->readp, bytes_wrap, &samplerate, &channels);
				if (n < 0) {
					found = -1;
				} else {
					_buf_inc_readp(streambuf, n);
					found = 1;
				}
			}

		} else {

			// mp4 - read header
			found = read_mp4_header(&samplerate, &channels);
		}

		if (found == 1) {

			LOG_INFO("samplerate: %u channels: %u", samplerate, channels);
			bytes_total = _buf_used(streambuf);
			bytes_wrap  = min(bytes_total, _buf_cont_read(streambuf));

			LOCK_O;
			LOG_INFO("setting track_start");
			output.next_sample_rate = decode_newstream(samplerate, output.supported_rates);
			IF_DSD( output.next_dop = false; )
void SteeringVehicle::update(const float currentTime, const float elapsedTime)
{
    SimpleVehicle::update(currentTime, elapsedTime);

    Vector3 pos = mCreature->getPosition();
	setPosition(pos);
    
    OgreNewt::Body* body = mCreature->getActor()->getPhysicalThing()->_getBody();
    //  Get the velocity vector
	mCurrentVelocity = body->getVelocity();
	//  enforce speed limit
	//  newVelocity = newVelocity.truncateLength(maxSpeed());
	//  update speed
	setSpeed(mCurrentVelocity.length());
	Vector3 newVelocity(mCurrentVelocity);

    //  regenerate local space(by default: align vehicle's forward axis with
    //  new velocity, but this behavior may be overridden by derived classes.)
    // use future orientation or not??
    Quaternion orientation(mController->getYaw(), Ogre::Vector3::UNIT_Y);
    Vector3 newUnitForward = orientation*Vector3::NEGATIVE_UNIT_Z;
    regenerateOrthonormalBasisUF(newUnitForward);

    // only process if mMovingCreature not NULL
    if (mController == NULL || mCreature->getQueryFlags() & QUERYFLAG_PLAYER)
    {
        mCurrentForce = Vector3::ZERO;
        return;
    }
    
    // calculate the result of the force    
    Vector3 result = mCurrentForce;// + mCurrentVelocity;
    
    mDebugSteer = mCurrentForce;

    // @todo remove this
    if (mCreature->getAu() <= 6)
        mCreature->modifyAu(20,true);

    AbstractMovement* mov_drehen = mController->getMovementFromId(CreatureController::MT_DREHEN);
    Real vel_drehen(0);
    Radian max_drehen = Degree(0);
    if (mov_drehen->calculateBaseVelocity(vel_drehen))
    {
        max_drehen = Degree(vel_drehen * 360 * elapsedTime);
    }

    Ogre::Quaternion future_orientation(mController->getYaw(), Ogre::Vector3::UNIT_Y);
    Ogre::Vector3 creatureDirection = future_orientation * Ogre::Vector3::NEGATIVE_UNIT_Z;
    Radian yaw(0);
    creatureDirection.y = result.y = 0;
    yaw = creatureDirection.getRotationTo(result, Ogre::Vector3::UNIT_Y).getYaw();
    if (yaw > Radian(0) && yaw > max_drehen)
        yaw = max_drehen;
    if (yaw < Radian(0) && yaw < -max_drehen)
        yaw = -max_drehen;

    Ogre::Vector3 direction(Ogre::Vector3::ZERO);
    Ogre::Vector3 rotation(0,yaw.valueRadians(),0);
    CreatureController::MovementType movement = CreatureController::MT_STEHEN;
    if (result != Ogre::Vector3::ZERO)
    {
        direction.z = -1;
        movement = CreatureController::MT_GEHEN;
    }

    mController->setMovement(movement, direction, rotation);
    LOG_DEBUG(Logger::AI, "SteeringVehicle: mController->setMovement " + 
        Ogre::StringConverter::toString(movement) + ", "
        + Ogre::StringConverter::toString(direction) + ", "
        + Ogre::StringConverter::toString(rotation));

	mCurrentForce = Ogre::Vector3::ZERO;
}
int argmax_fs_2i_base::_transformerServiceFunction( std::vector< gr_istream_base * > &istreams ,
    std::vector< gr_ostream_base * > &ostreams  )
{
    typedef std::vector< gr_istream_base * >   _IStreamList;
    typedef std::vector< gr_ostream_base * >  _OStreamList;

    boost::mutex::scoped_lock lock(serviceThreadLock);

    if ( validGRBlock() == false ) {

        // create our processing block, and setup  property notifiers
        createBlock();

        LOG_DEBUG( argmax_fs_2i_base, " FINISHED BUILDING  GNU RADIO BLOCK");
    }
 
    //process any Stream ID changes this could affect number of io streams
    processStreamIdChanges();

    if ( !validGRBlock() || istreams.size() == 0 || ostreams.size() == 0  ) {
        LOG_WARN( argmax_fs_2i_base, "NO STREAMS ATTACHED TO BLOCK..." );
        return NOOP;
    }

    _input_ready.resize( istreams.size() );
    _ninput_items_required.resize( istreams.size() );
    _ninput_items.resize( istreams.size() );
    _input_items.resize( istreams.size() );
    _output_items.resize( ostreams.size() );

    //
    // RESOLVE: need to look at forecast strategy, 
    //    1)  see how many read items are necessary for N number of outputs
    //    2)  read input data and see how much output we can produce
    //

    //
    // Grab available data from input streams
    //
    _OStreamList::iterator ostream;
    _IStreamList::iterator istream = istreams.begin();
    int nitems=0;
    for ( int idx=0 ; istream != istreams.end() && serviceThread->threadRunning() ; idx++, istream++ ) {
        // note this a blocking read that can cause deadlocks
        nitems = (*istream)->read();
    
        if ( (*istream)->overrun() ) {
            LOG_WARN( argmax_fs_2i_base, " NOT KEEPING UP WITH STREAM ID:" << (*istream)->streamID );
        }

        if ( (*istream)->sriChanged() ) {
            // RESOLVE - need to look at how SRI changes can affect Gnu Radio BLOCK state
            LOG_DEBUG( argmax_fs_2i_base, "SRI CHANGED, STREAMD IDX/ID: " 
                      << idx << "/" << (*istream)->getPktStreamId() );
            setOutputStreamSRI( idx, (*istream)->getPktSri() );
        }
    }

    LOG_TRACE( argmax_fs_2i_base, "READ NITEMS: "  << nitems );
    if ( nitems <= 0 && !_istreams[0]->eos() ) {
        return NOOP;
    }

    bool eos = false;
    int  nout = 0;
    bool workDone = false;

    while ( nout > -1 && serviceThread->threadRunning() ) {
        eos = false;
        nout = _forecastAndProcess( eos, istreams, ostreams );
        if ( nout > -1  ) {
            workDone = true;

            // we chunked on data so move read pointer..
            istream = istreams.begin();
            for ( ; istream != istreams.end(); istream++ ) {
                int idx=std::distance( istreams.begin(), istream );
                // if we processed data for this stream
                if ( _input_ready[idx] ) {
                    size_t nitems = 0;
                    try {
                        nitems = gr_sptr->nitems_read( idx );
                    } catch(...){}
      
                    if ( nitems > (*istream)->nitems() ) {
                        LOG_WARN( argmax_fs_2i_base,  "WORK CONSUMED MORE DATA THAN AVAILABLE,  READ/AVAILABLE "
                                 << nitems << "/" << (*istream)->nitems() );
                        nitems = (*istream)->nitems();
                    }
                    (*istream)->consume( nitems );
                    LOG_TRACE( argmax_fs_2i_base, " CONSUME READ DATA  ITEMS/REMAIN " << nitems << "/" << (*istream)->nitems());
                }
            }
            gr_sptr->reset_read_index();
        }

        // check for not enough data return
        if ( nout == -1 ) {

            // check for  end of stream
            istream = istreams.begin();
            for ( ; istream != istreams.end() ; istream++) {
                if ( (*istream)->eos() ) {
                    eos=true;
                }
            }
            if ( eos ) {
                LOG_TRACE(  argmax_fs_2i_base, "EOS SEEN, SENDING DOWNSTREAM " );
                _forecastAndProcess( eos, istreams, ostreams);
            }
        }
    }

    if ( eos ) {
        istream = istreams.begin();
        for ( ; istream != istreams.end() ; istream++ ) {
            int idx=std::distance( istreams.begin(), istream );
            LOG_DEBUG( argmax_fs_2i_base, " CLOSING INPUT STREAM IDX:" << idx );
            (*istream)->close();
        }

        // close remaining output streams
        ostream = ostreams.begin();
        for ( ; eos && ostream != ostreams.end(); ostream++ ) {
            int idx=std::distance( ostreams.begin(), ostream );
            LOG_DEBUG( argmax_fs_2i_base, " CLOSING OUTPUT STREAM IDX:" << idx );
            (*ostream)->close();
        }
    }

    //
    // set the read pointers of the GNU Radio Block to start at the beginning of the 
    // supplied buffers
    //
    gr_sptr->reset_read_index();

    LOG_TRACE( argmax_fs_2i_base, " END OF TRANSFORM SERVICE FUNCTION....." << noutput_items );

    if ( nout == -1 && eos == false && !workDone ) {
        return NOOP;
    } else {
        return NORMAL;
    }
}
int argmax_fs_2i_base::_forecastAndProcess( bool &eos, std::vector< gr_istream_base * > &istreams ,
                                 std::vector< gr_ostream_base * > &ostreams  )
{
    typedef std::vector< gr_istream_base * >   _IStreamList;
    typedef std::vector< gr_ostream_base * >  _OStreamList;

    _OStreamList::iterator ostream;
    _IStreamList::iterator istream = istreams.begin();
    int nout = 0;
    bool dataReady = false;
    if ( !eos ) {
        uint64_t max_items_avail = 0;
        for ( int idx=0 ; istream != istreams.end() && serviceThread->threadRunning() ; idx++, istream++ ) {
            LOG_TRACE( argmax_fs_2i_base, "GET MAX ITEMS: STREAM:"<< idx << " NITEMS/SCALARS:" << 
                       (*istream)->nitems() << "/" << (*istream)->nelems() );
            max_items_avail = std::max( (*istream)->nitems(), max_items_avail );
        }

        if ( max_items_avail == 0  ) {
            LOG_TRACE( argmax_fs_2i_base, "DATA CHECK - MAX ITEMS  NOUTPUT/MAX_ITEMS:" <<   noutput_items << "/" << max_items_avail);
            return -1;
        }

        //
        // calc number of output elements based on input items available
        //
        noutput_items = 0;
        if ( !gr_sptr->fixed_rate() )  {
            noutput_items = round_down((int32_t) (max_items_avail * gr_sptr->relative_rate()), gr_sptr->output_multiple());
            LOG_TRACE( argmax_fs_2i_base, " VARIABLE FORECAST NOUTPUT == " << noutput_items );
        } else {
            istream = istreams.begin();
            for ( int i=0; istream != istreams.end(); i++, istream++ ) {
                int t_noutput_items = gr_sptr->fixed_rate_ninput_to_noutput( (*istream)->nitems() );
                if ( gr_sptr->output_multiple_set() ) {
                    t_noutput_items = round_up(t_noutput_items, gr_sptr->output_multiple());
                }
                if ( t_noutput_items > 0 ) {
                    if ( noutput_items == 0 ) {
                        noutput_items = t_noutput_items;
                    }
                    if ( t_noutput_items <= noutput_items ) {
                        noutput_items = t_noutput_items;
                    }
                }
            }
            LOG_TRACE( argmax_fs_2i_base,  " FIXED FORECAST NOUTPUT/output_multiple == " << 
                        noutput_items  << "/" << gr_sptr->output_multiple());
        }

        //
        // ask the block how much input they need to produce noutput_items...
        // if enough data is available to process then set the dataReady flag
        //
        int32_t  outMultiple = gr_sptr->output_multiple();
        while ( !dataReady && noutput_items >= outMultiple  ) {
            //
            // ask the block how much input they need to produce noutput_items...
            //
            gr_sptr->forecast(noutput_items, _ninput_items_required);

            LOG_TRACE( argmax_fs_2i_base, "--> FORECAST IN/OUT " << _ninput_items_required[0]  << "/" << noutput_items  );

            istream = istreams.begin();
            uint32_t dr_cnt=0;
            for ( int idx=0 ; noutput_items > 0 && istream != istreams.end(); idx++, istream++ ) {
                // check if buffer has enough elements
                _input_ready[idx] = false;
                if ( (*istream)->nitems() >= (uint64_t)_ninput_items_required[idx] ) {
                    _input_ready[idx] = true;
                    dr_cnt++;
                }
                LOG_TRACE( argmax_fs_2i_base, "ISTREAM DATACHECK NELMS/NITEMS/REQ/READY:" <<   (*istream)->nelems() << 
                          "/" << (*istream)->nitems() << "/" << _ninput_items_required[idx] << "/" << _input_ready[idx]);
            }
    
            if ( dr_cnt < istreams.size() ) {
                if ( outMultiple > 1 ) {
                    noutput_items -= outMultiple;
                } else {
                    noutput_items /= 2;
                }
            } else {
                dataReady = true;
            }
            LOG_TRACE( argmax_fs_2i_base, " TRIM FORECAST NOUTPUT/READY " << noutput_items << "/" << dataReady );
        }

        // check if data is ready...
        if ( !dataReady ) {
            LOG_TRACE( argmax_fs_2i_base, "DATA CHECK - NOT ENOUGH DATA  AVAIL/REQ:" <<   _istreams[0]->nitems() << 
                      "/" << _ninput_items_required[0] );
            return -1;
        }

        // reset looping variables
        int  ritems = 0;
        int  nitems = 0;

        // reset caching vectors
        _output_items.clear();
        _input_items.clear();
        _ninput_items.clear();
        istream = istreams.begin();

        for ( int idx=0 ; istream != istreams.end(); idx++, istream++ ) {
            // check if the stream is ready
            if ( !_input_ready[idx] ) {
                continue;
            }
            // get number of items remaining
            try {
                ritems = gr_sptr->nitems_read( idx );
            } catch(...){
                // something bad has happened, we are missing an input stream
                LOG_ERROR( argmax_fs_2i_base, "MISSING INPUT STREAM FOR GR BLOCK, STREAM ID:" <<   (*istream)->streamID );
                return -2;
            } 
    
            nitems = (*istream)->nitems() - ritems;
            LOG_TRACE( argmax_fs_2i_base,  " ISTREAM: IDX:" << idx  << " ITEMS AVAIL/READ/REQ " << nitems << "/" 
                       << ritems << "/" << _ninput_items_required[idx] );
            if ( nitems >= _ninput_items_required[idx] && nitems > 0 ) {
                //remove eos checks ...if ( nitems < _ninput_items_required[idx] ) nitems=0;
                _ninput_items.push_back( nitems );
                _input_items.push_back( (*istream)->read_pointer(ritems) );
            }
        }

        //
        // setup output buffer vector based on noutput..
        //
        ostream = ostreams.begin();
        for( ; ostream != ostreams.end(); ostream++ ) {
            (*ostream)->resize(noutput_items);
            _output_items.push_back( (*ostream)->write_pointer() );
        }

        nout=0;
        if ( _input_items.size() != 0 && serviceThread->threadRunning() ) {
            LOG_TRACE( argmax_fs_2i_base, " CALLING WORK.....N_OUT:" << noutput_items << " N_IN:" << nitems 
                      << " ISTREAMS:" << _input_items.size() << " OSTREAMS:" << _output_items.size());
            nout = gr_sptr->general_work( noutput_items, _ninput_items, _input_items, _output_items);
            LOG_TRACE( argmax_fs_2i_base, "RETURN  WORK ..... N_OUT:" << nout);
        }

        // check for stop condition from work method
        if ( nout < gr_block::WORK_DONE ) {
            LOG_WARN( argmax_fs_2i_base, "WORK RETURNED STOP CONDITION..." << nout );
            nout=0;
            eos = true;
        }
    }

    if (nout != 0 or eos ) {
        noutput_items = nout;
        LOG_TRACE( argmax_fs_2i_base, " WORK RETURNED: NOUT : " << nout << " EOS:" << eos);
        ostream = ostreams.begin();

        for ( int idx=0 ; ostream != ostreams.end(); idx++, ostream++ ) {

            bool gotPkt = false;
            TimeStamp pktTs;
            int inputIdx = idx;
            if ( (size_t)(inputIdx) >= istreams.size() ) {
                for ( inputIdx= istreams.size()-1; inputIdx > -1; inputIdx--) {
                    if ( not istreams[inputIdx]->pktNull() ) {
                        gotPkt = true;
                        pktTs = istreams[inputIdx]->getPktTimeStamp();
                        break;
                    }
                }
            } else {
                pktTs = istreams[inputIdx]->getPktTimeStamp();
                if ( not istreams[inputIdx]->pktNull() ){
                    gotPkt = true;
                }
            }

            LOG_TRACE( argmax_fs_2i_base,  "PUSHING DATA   ITEMS/STREAM_ID " << (*ostream)->nitems() << "/" << (*ostream)->streamID );    
            if ( _maintainTimeStamp ) {

                // set time stamp for output samples based on input time stamp
                if ( (*ostream)->nelems() == 0 )  {
#ifdef TEST_TIME_STAMP
      LOG_DEBUG( argmax_fs_2i_base, "SEED - TS SRI:  xdelta:" << std::setprecision(12) << ostream->sri.xdelta );
      LOG_DEBUG( argmax_fs_2i_base, "OSTREAM WRITE:   maint:" << _maintainTimeStamp );
      LOG_DEBUG( argmax_fs_2i_base, "                  mode:" <<  ostream->tstamp.tcmode );
      LOG_DEBUG( argmax_fs_2i_base, "                status:" <<  ostream->tstamp.tcstatus );
      LOG_DEBUG( argmax_fs_2i_base, "                offset:" <<  ostream->tstamp.toff );
      LOG_DEBUG( argmax_fs_2i_base, "                 whole:" <<  std::setprecision(10) << ostream->tstamp.twsec );
      LOG_DEBUG( argmax_fs_2i_base, "SEED - TS         frac:" <<  std::setprecision(12) << ostream->tstamp.tfsec );
#endif
                    (*ostream)->setTimeStamp( pktTs, _maintainTimeStamp );
                }

                // write out samples, and set next time stamp based on xdelta and  noutput_items
                (*ostream)->write ( noutput_items, eos );
            } else {
// use incoming packet's time stamp to forward
                if ( gotPkt ) {
#ifdef TEST_TIME_STAMP
      LOG_DEBUG( argmax_fs_2i_base, "OSTREAM  SRI:  items/xdelta:" << noutput_items << "/" << std::setprecision(12) << ostream->sri.xdelta );
      LOG_DEBUG( argmax_fs_2i_base, "PKT - TS         maint:" << _maintainTimeStamp );
      LOG_DEBUG( argmax_fs_2i_base, "                  mode:" <<  pktTs.tcmode );
      LOG_DEBUG( argmax_fs_2i_base, "                status:" <<  pktTs.tcstatus );
      LOG_DEBUG( argmax_fs_2i_base, "                offset:" <<  pktTs.toff );
      LOG_DEBUG( argmax_fs_2i_base, "                 whole:" <<  std::setprecision(10) << pktTs.twsec );
      LOG_DEBUG( argmax_fs_2i_base, "PKT - TS          frac:" <<  std::setprecision(12) << pktTs.tfsec );
#endif
                    (*ostream)->write( noutput_items, eos, pktTs  );
                } else {
#ifdef TEST_TIME_STAMP
      LOG_DEBUG( argmax_fs_2i_base, "OSTREAM  SRI:  items/xdelta:" << noutput_items << "/" << std::setprecision(12) << ostream->sri.xdelta );
      LOG_DEBUG( argmax_fs_2i_base, "OSTREAM TOD      maint:" << _maintainTimeStamp );
      LOG_DEBUG( argmax_fs_2i_base, "                  mode:" <<  ostream->tstamp.tcmode );
      LOG_DEBUG( argmax_fs_2i_base, "                status:" <<  ostream->tstamp.tcstatus );
      LOG_DEBUG( argmax_fs_2i_base, "                offset:" <<  ostream->tstamp.toff );
      LOG_DEBUG( argmax_fs_2i_base, "                 whole:" <<  std::setprecision(10) << ostream->tstamp.twsec );
      LOG_DEBUG( argmax_fs_2i_base, "OSTREAM TOD       frac:" <<  std::setprecision(12) << ostream->tstamp.tfsec );
#endif
                    // use time of day as time stamp
                    (*ostream)->write( noutput_items, eos,  _maintainTimeStamp );
                }
            }

        } // for ostreams
    }

    return nout;     
}
Пример #10
0
static int swddp_transaction_endcheck(struct adiv5_dap *dap)
{
	int retval;
	uint32_t ctrlstat;

	/* too expensive to call keep_alive() here */

	/* Here be dragons!
	 *
	 * It is easy to be in a JTAG clock range where the target
	 * is not operating in a stable fashion. This happens
	 * for a few reasons:
	 *
	 * - the user may construct a simple test case to try to see
	 * if a higher JTAG clock works to eke out more performance.
	 * This simple case may pass, but more complex situations can
	 * fail.
	 *
	 * - The mostly works JTAG clock rate and the complete failure
	 * JTAG clock rate may be as much as 2-4x apart. This seems
	 * to be especially true on RC oscillator driven parts.
	 *
	 * So: even if calling adi_jtag_scan_inout_check_u32() multiple
	 * times here seems to "make things better here", it is just
	 * hiding problems with too high a JTAG clock.
	 *
	 * Note that even if some parts have RCLK/RTCK, that doesn't
	 * mean that RCLK/RTCK is the *correct* rate to run the JTAG
	 * interface at, i.e. RCLK/RTCK rates can be "too high", especially
	 * before the RC oscillator phase is not yet complete.
	 */

	/* Post CTRL/STAT read; discard any previous posted read value
	 * but collect its ACK status.
	 */
	retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
			DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
	if (retval != ERROR_OK)
		return retval;
	retval = jtag_execute_queue();
	if (retval != ERROR_OK)
		return retval;

	dap->ack = dap->ack & 0x7;

	/* common code path avoids calling timeval_ms() */
	if (dap->ack != SWD_ACK_OK) {
		long long then = timeval_ms();

		while (dap->ack != SWD_ACK_OK) {
			if (dap->ack == SWD_ACK_WAIT) {
				if ((timeval_ms()-then) > 1000) {
					/* NOTE:  this would be a good spot
					 * to use JTAG_DP_ABORT.
					 */
					LOG_WARNING("Timeout (1000ms) waiting "
						"for ACK=OK/FAULT "
						"in swd-DP transaction");
					return ERROR_JTAG_DEVICE_ERROR;
				}
			} else {
				LOG_WARNING("Invalid ACK %#x "
						"in swd-DP transaction",
						dap->ack);
				return ERROR_JTAG_DEVICE_ERROR;
			}

			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
			if (retval != ERROR_OK)
				return retval;
			retval = dap_run(dap);
			if (retval != ERROR_OK)
				return retval;
			dap->ack = dap->ack & 0x7;
		}
	}

	/* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */

	/* Check for STICKYERR and STICKYORUN */
	if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) {
		LOG_DEBUG("swd-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
		/* Check power to debug regions */
		if ((ctrlstat & 0xf0000000) != 0xf0000000) {
			retval = ahbap_debugport_init(dap);
			if (retval != ERROR_OK)
				return retval;
		} else {
			uint32_t mem_ap_csw, mem_ap_tar;

			/* Maybe print information about last intended
			 * MEM-AP access; but not if autoincrementing.
			 * *Real* CSW and TAR values are always shown.
			 */
			if (dap->ap_tar_value != (uint32_t) -1)
				LOG_DEBUG("MEM-AP Cached values: "
					"ap_bank 0x%" PRIx32
					", ap_csw 0x%" PRIx32
					", ap_tar 0x%" PRIx32,
					dap->ap_bank_value,
					dap->ap_csw_value,
					dap->ap_tar_value);

			if (ctrlstat & SSTICKYORUN)
				LOG_ERROR("SWD-DP OVERRUN - check clock, "
					"memaccess, or reduce swd speed");

			if (ctrlstat & SSTICKYERR)
				LOG_ERROR("SWD-DP STICKY ERROR");

			/* Clear Sticky Error Bits */
			// DIFF
			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
					DP_ABORT, DPAP_WRITE,
					dap->dp_ctrl_stat | ORUNERRCLR
						| STKERRCLR, NULL);
			if (retval != ERROR_OK)
				return retval;
			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
			if (retval != ERROR_OK)
				return retval;
			retval = dap_run(dap);
			if (retval != ERROR_OK)
				return retval;

			LOG_DEBUG("swd-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);

			retval = dap_queue_ap_read(dap,
					AP_REG_CSW, &mem_ap_csw);
			if (retval != ERROR_OK)
				return retval;

			retval = dap_queue_ap_read(dap,
					AP_REG_TAR, &mem_ap_tar);
			if (retval != ERROR_OK)
				return retval;

			retval = dap_run(dap);
			if (retval != ERROR_OK)
				return retval;
			LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%"
					PRIx32, mem_ap_csw, mem_ap_tar);

		}
		retval = dap_run(dap);
		if (retval != ERROR_OK)
			return retval;
		return ERROR_JTAG_DEVICE_ERROR;
	}

	return ERROR_OK;
}
void argmax_fs_2i_base::setupIOMappings( )
{
    int ninput_streams = 0;
    int noutput_streams = 0;
    std::string sid("");
    int inMode=RealMode;

    if ( !validGRBlock() ) return;
    ninput_streams  = gr_sptr->get_max_input_streams();
    gr_io_signature_sptr g_isig = gr_sptr->input_signature();

    noutput_streams = gr_sptr->get_max_output_streams();
    gr_io_signature_sptr g_osig = gr_sptr->output_signature();

    LOG_DEBUG( argmax_fs_2i_base, "GNUHAWK IO MAPPINGS IN/OUT " << ninput_streams << "/" << noutput_streams );

    //
    // Someone reset the GR Block so we need to clean up old mappings if they exists
    // we need to reset the io signatures and check the vlens
    //
    if ( _istreams.size() > 0 || _ostreams.size() > 0 ) {

        LOG_DEBUG( argmax_fs_2i_base, "RESET INPUT SIGNATURE SIZE:" << _istreams.size() );
        IStreamList::iterator istream;
        for ( int idx=0 ; istream != _istreams.end(); idx++, istream++ ) {
            // re-add existing stream definitons
            LOG_DEBUG(  argmax_fs_2i_base, "ADD READ INDEX TO GNU RADIO BLOCK");
            if ( ninput_streams == -1 ) gr_sptr->add_read_index();

            // setup io signature
            (*istream)->associate( gr_sptr );
        }

        LOG_DEBUG( argmax_fs_2i_base, "RESET OUTPUT SIGNATURE SIZE:" << _ostreams.size() );
        OStreamList::iterator ostream;
        for ( int idx=0 ; ostream != _ostreams.end(); idx++, ostream++ ) {
            // need to evaluate new settings...???
            (*ostream)->associate( gr_sptr );
        }

        return;
    }

    int i = 0;
   //
   // Setup mapping of RH port to GNU RADIO Block input streams
   // For version 1,  we are ignoring the GNU Radio input stream -1 case that allows multiple data 
   // streams over a single connection.  We are mapping a single RH Port to a single GNU Radio stream.
   // Stream Identifiers will  be pass along as they are received
   //
    LOG_TRACE( argmax_fs_2i_base, "setupIOMappings INPUT PORTS: " << inPorts.size() );
    RH_ProvidesPortMap::iterator p_in;
    i = 0;
    // grab ports based on their order in the scd.xml file
    p_in = inPorts.find("float_in_1");
    if ( p_in != inPorts.end() ) {
        bulkio::InFloatPort *port = dynamic_cast< bulkio::InFloatPort * >(p_in->second);
        int mode = inMode;
        sid = "";

        // need to add read index to GNU Radio Block for processing streams when max_input == -1
        if ( ninput_streams == -1 ) gr_sptr->add_read_index();

        // check if we received SRI during setup
        BULKIO::StreamSRISequence_var sris = port->activeSRIs();
        if (  sris->length() > 0 ) {
            BULKIO::StreamSRI sri = sris[sris->length()-1];
            mode = sri.mode;
        }
        std::vector<int> in;
        io_mapping.push_back( in );
        _istreams.push_back( new gr_istream< bulkio::InFloatPort > ( port, gr_sptr, i, mode, sid ));
        LOG_DEBUG( argmax_fs_2i_base, "ADDING INPUT MAP IDX:" << i << " SID:" << sid );
        // increment port counter
        i++;
    }

    // grab ports based on their order in the scd.xml file
    p_in = inPorts.find("float_in_2");
    if ( p_in != inPorts.end() ) {
        bulkio::InFloatPort *port = dynamic_cast< bulkio::InFloatPort * >(p_in->second);
        int mode = inMode;
        sid = "";

        // need to add read index to GNU Radio Block for processing streams when max_input == -1
        if ( ninput_streams == -1 ) gr_sptr->add_read_index();

        // check if we received SRI during setup
        BULKIO::StreamSRISequence_var sris = port->activeSRIs();
        if (  sris->length() > 0 ) {
            BULKIO::StreamSRI sri = sris[sris->length()-1];
            mode = sri.mode;
        }
        std::vector<int> in;
        io_mapping.push_back( in );
        _istreams.push_back( new gr_istream< bulkio::InFloatPort > ( port, gr_sptr, i, mode, sid ));
        LOG_DEBUG( argmax_fs_2i_base, "ADDING INPUT MAP IDX:" << i << " SID:" << sid );
        // increment port counter
        i++;
    }

    //
    // Setup mapping of RH port to GNU RADIO Block input streams
    // For version 1,  we are ignoring the GNU Radio output stream -1 case that allows multiple data 
    // streams over a single connection.  We are mapping a single RH Port to a single GNU Radio stream.
    //
    LOG_TRACE( argmax_fs_2i_base, "setupIOMappings OutputPorts: " << outPorts.size() );
    RH_UsesPortMap::iterator p_out;
    i = 0;
    // grab ports based on their order in the scd.xml file
    p_out = outPorts.find("short_out_1");
    if ( p_out != outPorts.end() ) {
        bulkio::OutShortPort *port = dynamic_cast< bulkio::OutShortPort * >(p_out->second);
        int idx = -1;
        BULKIO::StreamSRI sri = createOutputSRI( i, idx );
        if (idx == -1) idx = i;
        if(idx < (int)io_mapping.size()) io_mapping[idx].push_back(i);
        int mode = sri.mode;
        sid = sri.streamID;
        _ostreams.push_back( new gr_ostream< bulkio::OutShortPort > ( port, gr_sptr, i, mode, sid ));
        LOG_DEBUG( argmax_fs_2i_base, "ADDING OUTPUT MAP IDX:" << i << " SID:" << sid );
        _ostreams[i]->setSRI(sri, i );
        // increment port counter
        i++;
    }

    // grab ports based on their order in the scd.xml file
    p_out = outPorts.find("short_out_2");
    if ( p_out != outPorts.end() ) {
        bulkio::OutShortPort *port = dynamic_cast< bulkio::OutShortPort * >(p_out->second);
        int idx = -1;
        BULKIO::StreamSRI sri = createOutputSRI( i, idx );
        if (idx == -1) idx = i;
        if(idx < (int)io_mapping.size()) io_mapping[idx].push_back(i);
        int mode = sri.mode;
        sid = sri.streamID;
        _ostreams.push_back( new gr_ostream< bulkio::OutShortPort > ( port, gr_sptr, i, mode, sid ));
        LOG_DEBUG( argmax_fs_2i_base, "ADDING OUTPUT MAP IDX:" << i << " SID:" << sid );
        _ostreams[i]->setSRI(sri, i );
        // increment port counter
        i++;
    }

}
Пример #12
0
bool CHttpDownloader::download(std::list<IDownload*>& download)
{

	std::list<IDownload*>::iterator it;
	std::vector <DownloadData*> downloads;
	CURLM* curlm=curl_multi_init();
	for(it=download.begin(); it!=download.end(); ++it) {
		const int count=std::min(MAX_PARALLEL_DOWNLOADS, std::max(1, std::min((int)(*it)->pieces.size(), (*it)->getMirrorCount()))); //count of parallel downloads
		if((*it)->getMirrorCount()<=0) {
			LOG_ERROR("No mirrors found");
			return false;
		}
		LOG_DEBUG("Using %d parallel downloads", count);
		CFile* file=new CFile();
		if(!file->Open((*it)->name, (*it)->size, (*it)->piecesize)) {
			delete file;
			return false;
		}
		(*it)->file = file;
		for(int i=0; i<count; i++) {
			DownloadData* dlData=new DownloadData();
			dlData->download=*it;
			if (!setupDownload(dlData)) { //no piece found (all pieces already downloaded), skip
				delete dlData;
				if ((*it)->state!=IDownload::STATE_FINISHED) {
					LOG_ERROR("no piece found");
					return false;
				}
			} else {
				downloads.push_back(dlData);
				curl_multi_add_handle(curlm, dlData->easy_handle);
			}
		}
	}

	bool aborted=false;
	int running=1, last=-1;
	while((running>0)&&(!aborted)) {
		CURLMcode ret = CURLM_CALL_MULTI_PERFORM;
		while(ret == CURLM_CALL_MULTI_PERFORM) {
			ret=curl_multi_perform(curlm, &running);
		}
		if ( ret == CURLM_OK ) {
//			showProcess(download, file);
			if (last!=running) { //count of running downloads changed
				aborted=processMessages(curlm, downloads);
				last=running++;
			}
		} else {
			LOG_ERROR("curl_multi_perform_error: %d", ret);
			aborted=true;
		}

		fd_set rSet;
		fd_set wSet;
		fd_set eSet;

		FD_ZERO(&rSet);
		FD_ZERO(&wSet);
		FD_ZERO(&eSet);
		int count=0;
		struct timeval t;
		t.tv_sec = 1;
		t.tv_usec = 0;
		curl_multi_fdset(curlm, &rSet, &wSet, &eSet, &count);
		//sleep for one sec / until something happened
		select(count+1, &rSet, &wSet, &eSet, &t);
	}
	if (!aborted) { // if download didn't fail, get file size reported in http-header
		double size=-1;
		for (unsigned i=0; i<downloads.size(); i++) {
			double tmp;
			curl_easy_getinfo(downloads[i]->easy_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &tmp);
			if (tmp>size) {
				size=tmp;
			}
		}
		//set download size if isn't set and we have a valid number
//		if ((size>0) && (download->size<0)) {
//  		download->size = size;
//		}

	}
//	showProcess(download, file);
	LOG("\n");

	if (!aborted) {
		LOG_DEBUG("download complete");
	}

	//close all open files
	for(it=download.begin(); it!=download.end(); ++it) {
		if ((*it)->file!=NULL)
			(*it)->file->Close();
	}
	for (unsigned i=0; i<downloads.size(); i++) {
		long timestamp;
		if (curl_easy_getinfo(downloads[i]->easy_handle, CURLINFO_FILETIME, &timestamp) == CURLE_OK) {
			if (downloads[i]->download->state != IDownload::STATE_FINISHED) //decrease local timestamp if download failed to force redownload next time
				timestamp--;
			downloads[i]->download->file->SetTimestamp(timestamp);
		}
		delete downloads[i];
	}

	downloads.clear();
	curl_multi_cleanup(curlm);
	return !aborted;
}
Пример #13
0
bool CHttpDownloader::search(std::list<IDownload*>& res, const std::string& name, IDownload::category cat)
{
	LOG_DEBUG("%s", name.c_str()  );

	const std::string method(XMLRPC_METHOD);
	//std::string category;
	XmlRpc::XmlRpcClient client(XMLRPC_HOST,XMLRPC_PORT, XMLRPC_URI);
	XmlRpc::XmlRpcValue arg;
	arg["springname"]=name;
	arg["torrent"]=true;
	switch(cat) {
	case IDownload::CAT_MAPS:
		arg["category"]="map";
		break;
	case IDownload::CAT_GAMES:
		arg["category"]="game";
		break;
	case IDownload::CAT_ENGINE_LINUX:
		arg["category"]="engine_linux";
		break;
	case IDownload::CAT_ENGINE_LINUX64:
		arg["category"]="engine_linux64";
		break;
	case IDownload::CAT_ENGINE_WINDOWS:
		arg["category"]="engine_windows";
		break;
	case IDownload::CAT_ENGINE_MACOSX:
		arg["category"]="engine_macosx";
		break;
	default:
		break;
	}

	XmlRpc::XmlRpcValue result;
	client.execute(method.c_str(),arg, result);


	if (result.getType()!=XmlRpc::XmlRpcValue::TypeArray) {
		return false;
	}

	for(int i=0; i<result.size(); i++) {
		XmlRpc::XmlRpcValue resfile = result[i];

		if (resfile.getType()!=XmlRpc::XmlRpcValue::TypeStruct) {
			return false;
		}
		if (resfile["category"].getType()!=XmlRpc::XmlRpcValue::TypeString) {
			LOG_ERROR("No category in result");
			return false;
		}
		std::string filename=fileSystem->getSpringDir();
		std::string category=resfile["category"];
		filename+=PATH_DELIMITER;
		if (category=="map")
			filename+="maps";
		else if (category=="game")
			filename+="games";
		else if (category.find("engine")==0) // engine_windows, engine_linux, engine_macosx
			filename+="engine";
		else
			LOG_ERROR("Unknown Category %s", category.c_str());
		filename+=PATH_DELIMITER;
		if ((resfile["mirrors"].getType()!=XmlRpc::XmlRpcValue::TypeArray) ||
		    (resfile["filename"].getType()!=XmlRpc::XmlRpcValue::TypeString)) {
			LOG_ERROR("Invalid type in result");
			return false;
		}
		filename.append(resfile["filename"]);
		IDownload* dl=new IDownload(filename);
		XmlRpc::XmlRpcValue mirrors = resfile["mirrors"];
		for(int j=0; j<mirrors.size(); j++) {
			if (mirrors[j].getType()!=XmlRpc::XmlRpcValue::TypeString) {
				LOG_ERROR("Invalid type in result");
			} else {
				dl->addMirror(mirrors[j]);
			}
		}

		if(resfile["torrent"].getType()==XmlRpc::XmlRpcValue::TypeBase64) {
			const std::vector<char> torrent = resfile["torrent"];
			fileSystem->parseTorrent(&torrent[0], torrent.size(), dl);
		}
		if (resfile["version"].getType()==XmlRpc::XmlRpcValue::TypeString) {
			const std::string& version = resfile["version"];
			dl->version = version;
		}
		if (resfile["md5"].getType()==XmlRpc::XmlRpcValue::TypeString) {
			dl->hash=new HashMD5();
			dl->hash->Set(resfile["md5"]);
		}
		if (resfile["size"].getType()==XmlRpc::XmlRpcValue::TypeInt) {
			dl->size=resfile["size"];
		}
		if (resfile["depends"].getType() == XmlRpc::XmlRpcValue::TypeArray) {
			for(int i=0; i<resfile["depends"].size(); i++) {
				if (resfile["depends"][i].getType() == XmlRpc::XmlRpcValue::TypeString) {
					const std::string &dep = resfile["depends"][i];
					dl->addDepend(dep);
				}
			}
		}
		res.push_back(dl);
	}
	return true;
}
Пример #14
0
bool CHttpDownloader::processMessages(CURLM* curlm, std::vector <DownloadData*>& downloads)
{
	int msgs_left;
	HashSHA1 sha1;
	bool aborted=false;
	while(struct CURLMsg* msg=curl_multi_info_read(curlm, &msgs_left)) {
		switch(msg->msg) {
		case CURLMSG_DONE: { //a piece has been downloaded, verify it
			DownloadData* data=getDataByHandle(downloads, msg->easy_handle);
			switch(msg->data.result) {
			case CURLE_OK:
				break;
			case CURLE_HTTP_RETURNED_ERROR: //some 4* HTTP-Error (file not found, access denied,...)
			default:
				long http_code = 0;
				curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &http_code);
				LOG_ERROR("CURL error(%d): %s %d (%s)",msg->msg, curl_easy_strerror(msg->data.result), http_code, data->mirror->url.c_str());
				if (data->piece>=0) {
					data->download->pieces[data->piece].state=IDownload::STATE_NONE;
				}
				data->mirror->status=Mirror::STATUS_BROKEN;
				//FIXME: cleanup curl handle here + process next dl
			}
			if (data==NULL) {
				LOG_ERROR("Couldn't find download in download list");
				return false;
			}
			if (data->piece<0) { //download without pieces
				return false;
			}
			assert(data->download->file!=NULL);
			assert(data->piece< (int)data->download->pieces.size());
			if (data->download->pieces[data->piece].sha->isSet()) {
				data->download->file->Hash(sha1, data->piece);
				if (sha1.compare(data->download->pieces[data->piece].sha)) { //piece valid
					data->download->pieces[data->piece].state=IDownload::STATE_FINISHED;
					showProcess(data->download, true);
//					LOG("piece %d verified!", data->piece);
				} else { //piece download broken, mark mirror as broken (for this file)
					data->download->pieces[data->piece].state=IDownload::STATE_NONE;
					data->mirror->status=Mirror::STATUS_BROKEN;
					//FIXME: cleanup curl handle here + process next dl
				}
			} else {
				LOG_INFO("sha1 checksum seems to be not set, can't check received piece %d", data->piece);
			}
			//get speed at which this piece was downloaded + update mirror info
			double dlSpeed;
			curl_easy_getinfo(data->easy_handle, CURLINFO_SPEED_DOWNLOAD, &dlSpeed);
			data->mirror->UpdateSpeed(dlSpeed);
			if (data->mirror->status == Mirror::STATUS_UNKNOWN) //set mirror status only when unset
				data->mirror->status=Mirror::STATUS_OK;

			//remove easy handle, as its finished
			curl_multi_remove_handle(curlm, data->easy_handle);
			curl_easy_cleanup(data->easy_handle);
			data->easy_handle=NULL;

			//piece finished / failed, try a new one
			if (!setupDownload(data)) {
				LOG_DEBUG("No piece found, all pieces finished / currently downloading");
				break;
			}
			int ret=curl_multi_add_handle(curlm, data->easy_handle);
			if (ret!=CURLM_OK) {
				LOG_ERROR("curl_multi_perform_error: %d %d", ret, CURLM_BAD_EASY_HANDLE);
			}
			break;
		}
		default:
			LOG_ERROR("Unhandled message %d", msg->msg);
		}
	}
	return aborted;
}
Пример #15
0
int adaptor_init(zhandle_t *zh)
{
    pthread_mutexattr_t recursive_mx_attr;
    struct adaptor_threads *adaptor_threads = calloc(1, sizeof(*adaptor_threads));
    if (!adaptor_threads) {
        LOG_ERROR(("Out of memory"));
        return -1;
    }

    /* We use a pipe for interrupting select() in unix/sol and socketpair in windows. */
#ifdef WIN32   
    if (create_socket_pair(adaptor_threads->self_pipe) == -1){
       LOG_ERROR(("Can't make a socket."));
#else
    if(pipe(adaptor_threads->self_pipe)==-1) {
        LOG_ERROR(("Can't make a pipe %d",errno));
#endif
        free(adaptor_threads);
        return -1;
    }
    set_nonblock(adaptor_threads->self_pipe[1]);
    set_nonblock(adaptor_threads->self_pipe[0]);

    pthread_mutex_init(&zh->auth_h.lock,0);

    zh->adaptor_priv = adaptor_threads;
    pthread_mutex_init(&zh->to_process.lock,0);
    pthread_mutex_init(&adaptor_threads->zh_lock,0);
    // to_send must be recursive mutex    
    pthread_mutexattr_init(&recursive_mx_attr);
    pthread_mutexattr_settype(&recursive_mx_attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&zh->to_send.lock,&recursive_mx_attr);
    pthread_mutexattr_destroy(&recursive_mx_attr);
    
    pthread_mutex_init(&zh->sent_requests.lock,0);
    pthread_cond_init(&zh->sent_requests.cond,0);
    pthread_mutex_init(&zh->completions_to_process.lock,0);
    pthread_cond_init(&zh->completions_to_process.cond,0);
    start_threads(zh);
    return 0;
}

void adaptor_finish(zhandle_t *zh)
{
    struct adaptor_threads *adaptor_threads;
    // make sure zh doesn't get destroyed until after we're done here
    api_prolog(zh); 
    adaptor_threads = zh->adaptor_priv;
    if(adaptor_threads==0) {
        api_epilog(zh,0);
        return;
    }

    if(!pthread_equal(adaptor_threads->io,pthread_self())){
        wakeup_io_thread(zh);
        pthread_join(adaptor_threads->io, 0);
    }else
        pthread_detach(adaptor_threads->io);
    
    if(!pthread_equal(adaptor_threads->completion,pthread_self())){
        pthread_mutex_lock(&zh->completions_to_process.lock);
        pthread_cond_broadcast(&zh->completions_to_process.cond);
        pthread_mutex_unlock(&zh->completions_to_process.lock);
        pthread_join(adaptor_threads->completion, 0);
    }else
        pthread_detach(adaptor_threads->completion);
    
    api_epilog(zh,0);
}

void adaptor_destroy(zhandle_t *zh)
{
    struct adaptor_threads *adaptor = zh->adaptor_priv;
    if(adaptor==0) return;
    
    pthread_cond_destroy(&adaptor->cond);
    pthread_mutex_destroy(&adaptor->lock);
    pthread_mutex_destroy(&zh->to_process.lock);
    pthread_mutex_destroy(&zh->to_send.lock);
    pthread_mutex_destroy(&zh->sent_requests.lock);
    pthread_cond_destroy(&zh->sent_requests.cond);
    pthread_mutex_destroy(&zh->completions_to_process.lock);
    pthread_cond_destroy(&zh->completions_to_process.cond);
    pthread_mutex_destroy(&adaptor->zh_lock);

    pthread_mutex_destroy(&zh->auth_h.lock);

    close(adaptor->self_pipe[0]);
    close(adaptor->self_pipe[1]);
    free(adaptor);
    zh->adaptor_priv=0;
}

int wakeup_io_thread(zhandle_t *zh)
{
    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
    char c=0;
#ifndef WIN32
    return write(adaptor_threads->self_pipe[1],&c,1)==1? ZOK: ZSYSTEMERROR;    
#else
    return send(adaptor_threads->self_pipe[1], &c, 1, 0)==1? ZOK: ZSYSTEMERROR;    
#endif         
}

int adaptor_send_queue(zhandle_t *zh, int timeout)
{
    if(!zh->close_requested)
        return wakeup_io_thread(zh);
    // don't rely on the IO thread to send the messages if the app has
    // requested to close 
    return flush_send_queue(zh, timeout);
}

/* These two are declared here because we will run the event loop
 * and not the client */
#ifdef WIN32
int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest,
        struct timeval *tv);
#else
int zookeeper_interest(zhandle_t *zh, int *fd, int *interest,
        struct timeval *tv);
#endif
int zookeeper_process(zhandle_t *zh, int events);

#ifdef WIN32
unsigned __stdcall do_io( void * v)
#else
void *do_io(void *v)
#endif
{
    zhandle_t *zh = (zhandle_t*)v;
#ifndef WIN32
    struct pollfd fds[2];
    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;

    api_prolog(zh);
    notify_thread_ready(zh);
    LOG_DEBUG(("started IO thread"));
    fds[0].fd=adaptor_threads->self_pipe[0];
    fds[0].events=POLLIN;
    while(!zh->close_requested) {
        struct timeval tv;
        int fd;
        int interest;
        int timeout;
        int maxfd=1;
        int rc;
        
        zookeeper_interest(zh, &fd, &interest, &tv);
        if (fd != -1) {
            fds[1].fd=fd;
            fds[1].events=(interest&ZOOKEEPER_READ)?POLLIN:0;
            fds[1].events|=(interest&ZOOKEEPER_WRITE)?POLLOUT:0;
            maxfd=2;
        }
        timeout=tv.tv_sec * 1000 + (tv.tv_usec/1000);
        
        poll(fds,maxfd,timeout);
        if (fd != -1) {
            interest=(fds[1].revents&POLLIN)?ZOOKEEPER_READ:0;
            interest|=((fds[1].revents&POLLOUT)||(fds[1].revents&POLLHUP))?ZOOKEEPER_WRITE:0;
        }
        if(fds[0].revents&POLLIN){
            // flush the pipe
            char b[128];
            while(read(adaptor_threads->self_pipe[0],b,sizeof(b))==sizeof(b)){}
        }        
#else
    fd_set rfds, wfds, efds;
    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
    api_prolog(zh);
    notify_thread_ready(zh);
    LOG_DEBUG(("started IO thread"));
    FD_ZERO(&rfds);   FD_ZERO(&wfds);    FD_ZERO(&efds);
    while(!zh->close_requested) {      
        struct timeval tv;
        SOCKET fd;
        SOCKET maxfd=adaptor_threads->self_pipe[0];
        int interest;        
        int rc;
               
       zookeeper_interest(zh, &fd, &interest, &tv);
       if (fd != -1) {
           if (interest&ZOOKEEPER_READ) {
                FD_SET(fd, &rfds);
            } else {
                FD_CLR(fd, &rfds);
            }
           if (interest&ZOOKEEPER_WRITE) {
                FD_SET(fd, &wfds);
            } else {
                FD_CLR(fd, &wfds);
            }                  
        }
       FD_SET( adaptor_threads->self_pipe[0] ,&rfds );        
       rc = select((int)maxfd, &rfds, &wfds, &efds, &tv);
       if (fd != -1) 
       {
           interest = (FD_ISSET(fd, &rfds))? ZOOKEEPER_READ:0;
           interest|= (FD_ISSET(fd, &wfds))? ZOOKEEPER_WRITE:0;
        }
               
       if (FD_ISSET(adaptor_threads->self_pipe[0], &rfds)){
            // flush the pipe/socket
            char b[128];
           while(recv(adaptor_threads->self_pipe[0],b,sizeof(b), 0)==sizeof(b)){}
       }
#endif
        // dispatch zookeeper events
        rc = zookeeper_process(zh, interest);
        // check the current state of the zhandle and terminate 
        // if it is_unrecoverable()
        if(is_unrecoverable(zh))
            break;
    }
    api_epilog(zh, 0);    
    LOG_DEBUG(("IO thread terminated"));
    return 0;
}

#ifdef WIN32
unsigned __stdcall do_completion( void * v)
#else
void *do_completion(void *v)
#endif
{
    zhandle_t *zh = v;
    api_prolog(zh);
    notify_thread_ready(zh);
    LOG_DEBUG(("started completion thread"));
    while(!zh->close_requested) {
        pthread_mutex_lock(&zh->completions_to_process.lock);
        while(!zh->completions_to_process.head && !zh->close_requested) {
            pthread_cond_wait(&zh->completions_to_process.cond, &zh->completions_to_process.lock);
        }
        pthread_mutex_unlock(&zh->completions_to_process.lock);
        process_completions(zh);
    }
    api_epilog(zh, 0);    
    LOG_DEBUG(("completion thread terminated"));
    return 0;
}
Пример #16
0
/**
 * Save processor state.  This is called after a HALT instruction
 * succeeds, and on other occasions the processor enters debug mode
 * (breakpoint, watchpoint, etc).  Caller has updated arm11->dscr.
 */
static int arm11_debug_entry(struct arm11_common *arm11)
{
	int retval;

	arm11->arm.target->state = TARGET_HALTED;
	arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);

	/* REVISIT entire cache should already be invalid !!! */
	register_cache_invalidate(arm11->arm.core_cache);

	/* See e.g. ARM1136 TRM, "14.8.4 Entering Debug state" */

	/* maybe save wDTR (pending DCC write to debug SW, e.g. libdcc) */
	arm11->is_wdtr_saved = !!(arm11->dscr & DSCR_DTR_TX_FULL);
	if (arm11->is_wdtr_saved)
	{
		arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);

		arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

		struct scan_field	chain5_fields[3];

		arm11_setup_field(arm11, 32, NULL,
				&arm11->saved_wdtr, chain5_fields + 0);
		arm11_setup_field(arm11,  1, NULL, NULL,		chain5_fields + 1);
		arm11_setup_field(arm11,  1, NULL, NULL,		chain5_fields + 2);

		arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE);

	}

	/* DSCR: set the Execute ARM instruction enable bit.
	 *
	 * ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode",
	 * but not to issue ITRs(?).  The ARMv7 arch spec says it's required
	 * for executing instructions via ITR.
	 */
	arm11_write_DSCR(arm11, DSCR_ITR_EN | arm11->dscr);


	/* From the spec:
	   Before executing any instruction in debug state you have to drain the write buffer.
	   This ensures that no imprecise Data Aborts can return at a later point:*/

	/** \todo TODO: Test drain write buffer. */

#if 0
	while (1)
	{
		/* MRC p14,0,R0,c5,c10,0 */
		//	arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);

		/* mcr	   15, 0, r0, cr7, cr10, {4} */
		arm11_run_instr_no_data1(arm11, 0xee070f9a);

		uint32_t dscr = arm11_read_DSCR(arm11);

		LOG_DEBUG("DRAIN, DSCR %08x", dscr);

		if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT)
		{
			arm11_run_instr_no_data1(arm11, 0xe320f000);

			dscr = arm11_read_DSCR(arm11);

			LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr);

			break;
		}
	}
#endif

	/* Save registers.
	 *
	 * NOTE:  ARM1136 TRM suggests saving just R0 here now, then
	 * CPSR and PC after the rDTR stuff.  We do it all at once.
	 */
	retval = arm_dpm_read_current_registers(&arm11->dpm);
	if (retval != ERROR_OK)
		LOG_ERROR("DPM REG READ -- fail %d", retval);

	retval = arm11_run_instr_data_prepare(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* maybe save rDTR (pending DCC read from debug SW, e.g. libdcc) */
	arm11->is_rdtr_saved = !!(arm11->dscr & DSCR_DTR_RX_FULL);
	if (arm11->is_rdtr_saved)
	{
		/* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */
		retval = arm11_run_instr_data_from_core_via_r0(arm11,
				0xEE100E15, &arm11->saved_rdtr);
		if (retval != ERROR_OK)
			return retval;
	}

	/* REVISIT Now that we've saved core state, there's may also
	 * be MMU and cache state to care about ...
	 */

	if (arm11->simulate_reset_on_next_halt)
	{
		arm11->simulate_reset_on_next_halt = false;

		LOG_DEBUG("Reset c1 Control Register");

		/* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */

		/* MCR p15,0,R0,c1,c0,0 */
		retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
		if (retval != ERROR_OK)
			return retval;

	}

	if (arm11->arm.target->debug_reason == DBG_REASON_WATCHPOINT) {
		uint32_t wfar;

		/* MRC p15, 0, <Rd>, c6, c0, 1 ; Read WFAR */
		retval = arm11_run_instr_data_from_core_via_r0(arm11,
				ARMV4_5_MRC(15, 0, 0, 6, 0, 1),
				&wfar);
		if (retval != ERROR_OK)
			return retval;
		arm_dpm_report_wfar(arm11->arm.dpm, wfar);
	}


	retval = arm11_run_instr_data_finish(arm11);
	if (retval != ERROR_OK)
		return retval;

	return ERROR_OK;
}
Пример #17
0
// read mp4 header to extract config data
static int read_mp4_header(unsigned long *samplerate_p, unsigned char *channels_p) {
	size_t bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
	char type[5];
	u32_t len;

	while (bytes >= 8) {
		// count trak to find the first playable one
		static unsigned trak, play;
		u32_t consume;

		len = unpackN((u32_t *)streambuf->readp);
		memcpy(type, streambuf->readp + 4, 4);
		type[4] = '\0';

		if (!strcmp(type, "moov")) {
			trak = 0;
			play = 0;
		}
		if (!strcmp(type, "trak")) {
			trak++;
		}

		// extract audio config from within esds and pass to DecInit2
		if (!strcmp(type, "esds") && bytes > len) {
			unsigned config_len;
			u8_t *ptr = streambuf->readp + 12;
			if (*ptr++ == 0x03) {
				mp4_desc_length(&ptr);
				ptr += 4;
			} else {
				ptr += 3;
			}
			mp4_desc_length(&ptr);
			ptr += 13;
			if (*ptr++ != 0x05) {
				LOG_WARN("error parsing esds");
				return -1;
			}
			config_len = mp4_desc_length(&ptr);
			if (NEAAC(a, Init2, a->hAac, ptr, config_len, samplerate_p, channels_p) == 0) {
				LOG_DEBUG("playable aac track: %u", trak);
				play = trak;
			}
		}

		// extract the total number of samples from stts
		if (!strcmp(type, "stts") && bytes > len) {
			u32_t i;
			u8_t *ptr = streambuf->readp + 12;
			u32_t entries = unpackN((u32_t *)ptr);
			ptr += 4;
			for (i = 0; i < entries; ++i) {
				u32_t count = unpackN((u32_t *)ptr);
				u32_t size = unpackN((u32_t *)(ptr + 4));
				a->sttssamples += count * size;
				ptr += 8;
			}
			LOG_DEBUG("total number of samples contained in stts: " FMT_u64, a->sttssamples);
		}

		// stash sample to chunk info, assume it comes before stco
		if (!strcmp(type, "stsc") && bytes > len && !a->chunkinfo) {
			a->stsc = malloc(len - 12);
			if (a->stsc == NULL) {
				LOG_WARN("malloc fail");
				return -1;
			}
			memcpy(a->stsc, streambuf->readp + 12, len - 12);
		}

		// build offsets table from stco and stored stsc
		if (!strcmp(type, "stco") && bytes > len && play == trak) {
			u32_t i;
			// extract chunk offsets
			u8_t *ptr = streambuf->readp + 12;
			u32_t entries = unpackN((u32_t *)ptr);
			ptr += 4;
			a->chunkinfo = malloc(sizeof(struct chunk_table) * (entries + 1));
			if (a->chunkinfo == NULL) {
				LOG_WARN("malloc fail");
				return -1;
			}
			for (i = 0; i < entries; ++i) {
				a->chunkinfo[i].offset = unpackN((u32_t *)ptr);
				a->chunkinfo[i].sample = 0;
				ptr += 4;
			}
			a->chunkinfo[i].sample = 0;
			a->chunkinfo[i].offset = 0;
			// fill in first sample id for each chunk from stored stsc
			if (a->stsc) {
				u32_t stsc_entries = unpackN((u32_t *)a->stsc);
				u32_t sample = 0;
				u32_t last = 0, last_samples = 0;
				u8_t *ptr = (u8_t *)a->stsc + 4;
				while (stsc_entries--) {
					u32_t first = unpackN((u32_t *)ptr);
					u32_t samples = unpackN((u32_t *)(ptr + 4));
					if (last) {
						for (i = last - 1; i < first - 1; ++i) {
							a->chunkinfo[i].sample = sample;
							sample += last_samples;
						}
					}
					if (stsc_entries == 0) {
						for (i = first - 1; i < entries; ++i) {
							a->chunkinfo[i].sample = sample;
							sample += samples;
						}
					}
					last = first;
					last_samples = samples;
					ptr += 12;
				}
				free(a->stsc);
				a->stsc = NULL;
			}
		}

		// found media data, advance to start of first chunk and return
		if (!strcmp(type, "mdat")) {
			_buf_inc_readp(streambuf, 8);
			a->pos += 8;
			bytes  -= 8;
			if (play) {
				LOG_DEBUG("type: mdat len: %u pos: %u", len, a->pos);
				if (a->chunkinfo && a->chunkinfo[0].offset > a->pos) {
					u32_t skip = a->chunkinfo[0].offset - a->pos; 	
					LOG_DEBUG("skipping: %u", skip);
					if (skip <= bytes) {
						_buf_inc_readp(streambuf, skip);
						a->pos += skip;
					} else {
						a->consume = skip;
					}
				}
				a->sample = a->nextchunk = 1;
				return 1;
			} else {
				LOG_DEBUG("type: mdat len: %u, no playable track found", len);
				return -1;
			}
		}

		// parse key-value atoms within ilst ---- entries to get encoder padding within iTunSMPB entry for gapless
		if (!strcmp(type, "----") && bytes > len) {
			u8_t *ptr = streambuf->readp + 8;
			u32_t remain = len - 8, size;
			if (!memcmp(ptr + 4, "mean", 4) && (size = unpackN((u32_t *)ptr)) < remain) {
				ptr += size; remain -= size;
			}
			if (!memcmp(ptr + 4, "name", 4) && (size = unpackN((u32_t *)ptr)) < remain && !memcmp(ptr + 12, "iTunSMPB", 8)) {
				ptr += size; remain -= size;
			}
			if (!memcmp(ptr + 4, "data", 4) && remain > 16 + 48) {
				// data is stored as hex strings: 0 start end samples
				u32_t b, c; u64_t d;
				if (sscanf((const char *)(ptr + 16), "%x %x %x " FMT_x64, &b, &b, &c, &d) == 4) {
					LOG_DEBUG("iTunSMPB start: %u end: %u samples: " FMT_u64, b, c, d);
					if (a->sttssamples && a->sttssamples < b + c + d) {
						LOG_DEBUG("reducing samples as stts count is less");
						d = a->sttssamples - (b + c);
					}
					a->skip = b;
					a->samples = d;
				}
			}
		}

		// default to consuming entire box
		consume = len;

		// read into these boxes so reduce consume
		if (!strcmp(type, "moov") || !strcmp(type, "trak") || !strcmp(type, "mdia") || !strcmp(type, "minf") || !strcmp(type, "stbl") ||
			!strcmp(type, "udta") || !strcmp(type, "ilst")) {
			consume = 8;
		}
		// special cases which mix mix data in the enclosing box which we want to read into
		if (!strcmp(type, "stsd")) consume = 16;
		if (!strcmp(type, "mp4a")) consume = 36;
		if (!strcmp(type, "meta")) consume = 12;

		// consume rest of box if it has been parsed (all in the buffer) or is not one we want to parse
		if (bytes >= consume) {
			LOG_DEBUG("type: %s len: %u consume: %u", type, len, consume);
			_buf_inc_readp(streambuf, consume);
			a->pos += consume;
			bytes -= consume;
		} else if ( !(!strcmp(type, "esds") || !strcmp(type, "stts") || !strcmp(type, "stsc") || 
					 !strcmp(type, "stco") || !strcmp(type, "----")) ) {
			LOG_DEBUG("type: %s len: %u consume: %u - partial consume: %u", type, len, consume, bytes);
			_buf_inc_readp(streambuf, bytes);
			a->pos += bytes;
			a->consume = consume - bytes;
			break;
		} else {
			break;
		}
	}

	return 0;
}
Пример #18
0
/* talk to the target and set things up */
static int arm11_examine(struct target *target)
{
	int retval;
	char *type;
	struct arm11_common *arm11 = target_to_arm11(target);
	uint32_t didr, device_id;
	uint8_t implementor;

	/* FIXME split into do-first-time and do-every-time logic ... */

	/* check IDCODE */

	arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);

	struct scan_field		idcode_field;

	arm11_setup_field(arm11, 32, NULL, &device_id, &idcode_field);

	arm11_add_dr_scan_vc(1, &idcode_field, TAP_DRPAUSE);

	/* check DIDR */

	arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT);

	arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

	struct scan_field		chain0_fields[2];

	arm11_setup_field(arm11, 32, NULL, &didr, chain0_fields + 0);
	arm11_setup_field(arm11,  8, NULL, &implementor, chain0_fields + 1);

	arm11_add_dr_scan_vc(ARRAY_SIZE(chain0_fields), chain0_fields, TAP_IDLE);

	CHECK_RETVAL(jtag_execute_queue());

	/* assume the manufacturer id is ok; check the part # */
	switch ((device_id >> 12) & 0xFFFF)
	{
	case 0x7B36:
		type = "ARM1136";
		break;
	case 0x7B37:
		type = "ARM11 MPCore";
		break;
	case 0x7B56:
		type = "ARM1156";
		break;
	case 0x7B76:
		arm11->arm.core_type = ARM_MODE_MON;
		type = "ARM1176";
		break;
	default:
		LOG_ERROR("unexpected ARM11 ID code");
		return ERROR_FAIL;
	}
	LOG_INFO("found %s", type);

	/* unlikely this could ever fail, but ... */
	switch ((didr >> 16) & 0x0F) {
	case ARM11_DEBUG_V6:
	case ARM11_DEBUG_V61:		/* supports security extensions */
		break;
	default:
		LOG_ERROR("Only ARM v6 and v6.1 debug supported.");
		return ERROR_FAIL;
	}

	arm11->brp = ((didr >> 24) & 0x0F) + 1;

	/** \todo TODO: reserve one brp slot if we allow breakpoints during step */
	arm11->free_brps = arm11->brp;

	LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32,
			device_id, implementor, didr);

	/* as a side-effect this reads DSCR and thus
	 * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
	 * as suggested by the spec.
	 */

	retval = arm11_check_init(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* Build register cache "late", after target_init(), since we
	 * want to know if this core supports Secure Monitor mode.
	 */
	if (!target_was_examined(target))
		retval = arm11_dpm_init(arm11, didr);

	/* ETM on ARM11 still uses original scanchain 6 access mode */
	if (arm11->arm.etm && !target_was_examined(target)) {
		*register_get_last_cache_p(&target->reg_cache) =
			etm_build_reg_cache(target, &arm11->jtag_info,
					arm11->arm.etm);
		retval = etm_setup(target);
	}

	target_set_examined(target);

	return ERROR_OK;
}
Пример #19
0
pj_status_t init_stack(const std::string& system_name,
                       const std::string& sas_address,
                       int pcscf_trusted_port,
                       int pcscf_untrusted_port,
                       int scscf_port,
                       int icscf_port,
                       const std::string& local_host,
                       const std::string& public_host,
                       const std::string& home_domain,
                       const std::string& additional_home_domains,
                       const std::string& scscf_uri,
                       const std::string& alias_hosts,
                       SIPResolver* sipresolver,
                       int num_pjsip_threads,
                       int record_routing_model,
                       const int default_session_expires,
                       const int max_session_expires,
                       QuiescingManager *quiescing_mgr_arg,
                       const std::string& cdf_domain)
{
  pj_status_t status;
  pj_sockaddr pri_addr;
  pj_sockaddr addr_list[16];
  unsigned addr_cnt = PJ_ARRAY_SIZE(addr_list);
  unsigned i;

  // Set up the vectors of threads.  The threads don't get created until
  // start_pjsip_threads is called.
  pjsip_threads.resize(num_pjsip_threads);


  // Get ports and host names specified on options.  If local host was not
  // specified, use the host name returned by pj_gethostname.
  char* local_host_cstr = strdup(local_host.c_str());
  char* public_host_cstr = strdup(public_host.c_str());
  char* home_domain_cstr = strdup(home_domain.c_str());
  char* scscf_uri_cstr;
  if (scscf_uri.empty())
  {
    // Create a default S-CSCF URI using the localhost and S-CSCF port.
    std::string tmp_scscf_uri = "sip:" + local_host + ":" + std::to_string(scscf_port) + ";transport=TCP";
    scscf_uri_cstr = strdup(tmp_scscf_uri.c_str());
  }
  else
  {
    // Use the specified URI.
    scscf_uri_cstr = strdup(scscf_uri.c_str());
  }

  // This is only set on Bono nodes (it's the empty string otherwise)
  char* cdf_domain_cstr = strdup(cdf_domain.c_str());

  // Copy port numbers to stack data.
  stack_data.pcscf_trusted_port = pcscf_trusted_port;
  stack_data.pcscf_untrusted_port = pcscf_untrusted_port;
  stack_data.scscf_port = scscf_port;
  stack_data.icscf_port = icscf_port;

  stack_data.sipresolver = sipresolver;

  // Copy other functional options to stack data.
  stack_data.default_session_expires = default_session_expires;
  stack_data.max_session_expires = max_session_expires;

  // Work out local and public hostnames and cluster domain names.
  stack_data.local_host = (local_host != "") ? pj_str(local_host_cstr) : *pj_gethostname();
  stack_data.public_host = (public_host != "") ? pj_str(public_host_cstr) : stack_data.local_host;
  stack_data.default_home_domain = (home_domain != "") ? pj_str(home_domain_cstr) : stack_data.local_host;
  stack_data.scscf_uri = pj_str(scscf_uri_cstr);
  stack_data.cdf_domain = pj_str(cdf_domain_cstr);

  // Build a set of home domains
  stack_data.home_domains = std::unordered_set<std::string>();
  stack_data.home_domains.insert(PJUtils::pj_str_to_string(&stack_data.default_home_domain));
  if (additional_home_domains != "")
  {
    std::list<std::string> domains;
    Utils::split_string(additional_home_domains, ',', domains, 0, true);
    stack_data.home_domains.insert(domains.begin(), domains.end());
  }

  // Set up the default address family.  This is IPv4 unless our local host is an IPv6 address.
  stack_data.addr_family = AF_INET;
  struct in6_addr dummy_addr;
  if (inet_pton(AF_INET6, local_host_cstr, &dummy_addr) == 1)
  {
    LOG_DEBUG("Local host is an IPv6 address - enabling IPv6 mode");
    stack_data.addr_family = AF_INET6;
  }

  stack_data.record_route_on_every_hop = false;
  stack_data.record_route_on_initiation_of_originating = false;
  stack_data.record_route_on_initiation_of_terminating = false;
  stack_data.record_route_on_completion_of_originating = false;
  stack_data.record_route_on_completion_of_terminating = false;
  stack_data.record_route_on_diversion = false;

  if (scscf_port != 0)
  {
    switch (record_routing_model)
    {
    case 1:
      stack_data.record_route_on_initiation_of_originating = true;
      stack_data.record_route_on_completion_of_terminating = true;
      break;
    case 2:
      stack_data.record_route_on_initiation_of_originating = true;
      stack_data.record_route_on_initiation_of_terminating = true;
      stack_data.record_route_on_completion_of_originating = true;
      stack_data.record_route_on_completion_of_terminating = true;
      stack_data.record_route_on_diversion = true;
      break;
    case 3:
      stack_data.record_route_on_every_hop = true;
      stack_data.record_route_on_initiation_of_originating = true;
      stack_data.record_route_on_initiation_of_terminating = true;
      stack_data.record_route_on_completion_of_originating = true;
      stack_data.record_route_on_completion_of_terminating = true;
      stack_data.record_route_on_diversion = true;
      break;
    default:
      LOG_ERROR("Record-Route setting should be 1, 2, or 3, is %d. Defaulting to Record-Route on every hop.", record_routing_model);
      stack_data.record_route_on_every_hop = true;
    }
  }

  std::string system_name_sas = system_name;
  std::string system_type_sas = (pcscf_trusted_port != 0) ? "bono" : "sprout";
  // Initialize SAS logging.
  if (system_name_sas == "")
  {
    system_name_sas = std::string(stack_data.local_host.ptr, stack_data.local_host.slen);
  }
  SAS::init(system_name,
            system_type_sas,
            SASEvent::CURRENT_RESOURCE_BUNDLE,
            sas_address,
            sas_write);

  // Initialise PJSIP and all the associated resources.
  status = init_pjsip();

  // Initialize the PJUtils module.
  PJUtils::init();

  // Create listening transports for the ports whichtrusted and untrusted ports.
  stack_data.pcscf_trusted_tcp_factory = NULL;
  if (stack_data.pcscf_trusted_port != 0)
  {
    status = start_transports(stack_data.pcscf_trusted_port,
                              stack_data.local_host,
                              &stack_data.pcscf_trusted_tcp_factory);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
  }

  stack_data.pcscf_untrusted_tcp_factory = NULL;
  if (stack_data.pcscf_untrusted_port != 0)
  {
    status = start_transports(stack_data.pcscf_untrusted_port,
                              stack_data.public_host,
                              &stack_data.pcscf_untrusted_tcp_factory);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
  }

  stack_data.scscf_tcp_factory = NULL;
  if (stack_data.scscf_port != 0)
  {
    status = start_transports(stack_data.scscf_port,
                              stack_data.public_host,
                              &stack_data.scscf_tcp_factory);
    if (status == PJ_SUCCESS)
    {
      CL_SPROUT_S_CSCF_AVAIL.log(stack_data.scscf_port);
    }
    else
    {
      CL_SPROUT_S_CSCF_INIT_FAIL2.log(stack_data.scscf_port);
    }
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
  }

  stack_data.icscf_tcp_factory = NULL;
  if (stack_data.icscf_port != 0)
  {
    status = start_transports(stack_data.icscf_port,
                              stack_data.public_host,
                              &stack_data.icscf_tcp_factory);
    if (status == PJ_SUCCESS)
    {
      CL_SPROUT_I_CSCF_AVAIL.log(stack_data.icscf_port);
    }
    else
    {
      CL_SPROUT_I_CSCF_INIT_FAIL2.log(stack_data.icscf_port);
    }
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
  }

  // List all names matching local endpoint.
  // Note that PJLIB version 0.6 and newer has a function to
  // enumerate local IP interface (pj_enum_ip_interface()), so
  // by using it would be possible to list all IP interfaces in
  // this host.

  // The first address is important since this would be the one
  // to be added in Record-Route.
  stack_data.name[stack_data.name_cnt] = stack_data.local_host;
  stack_data.name_cnt++;

  if (strcmp(local_host_cstr, public_host_cstr))
  {
    stack_data.name[stack_data.name_cnt] = stack_data.public_host;
    stack_data.name_cnt++;
  }

  if ((scscf_port != 0) &&
      (!scscf_uri.empty()))
  {
    // S-CSCF enabled with a specified URI, so add host name from the URI to hostnames.
    pjsip_sip_uri* uri = (pjsip_sip_uri*)PJUtils::uri_from_string(scscf_uri,
                                                                  stack_data.pool);
    if (uri != NULL)
    {
      stack_data.name[stack_data.name_cnt] = uri->host;
      stack_data.name_cnt++;
    }
  }

  if (pj_gethostip(pj_AF_INET(), &pri_addr) == PJ_SUCCESS)
  {
    pj_strdup2(stack_data.pool, &stack_data.name[stack_data.name_cnt],
               pj_inet_ntoa(pri_addr.ipv4.sin_addr));
    stack_data.name_cnt++;
  }

  // Get the rest of IP interfaces.
  if (pj_enum_ip_interface(pj_AF_INET(), &addr_cnt, addr_list) == PJ_SUCCESS)
  {
    for (i = 0; i < addr_cnt; ++i)
    {
      if (addr_list[i].ipv4.sin_addr.s_addr == pri_addr.ipv4.sin_addr.s_addr)
      {
        continue;
      }

      pj_strdup2(stack_data.pool, &stack_data.name[stack_data.name_cnt],
                 pj_inet_ntoa(addr_list[i].ipv4.sin_addr));
      stack_data.name_cnt++;
    }
  }

  // Note that we no longer consider 127.0.0.1 and localhost as aliases.

  // Parse the list of alias host names.
  stack_data.aliases = std::unordered_set<std::string>();
  if (alias_hosts != "")
  {
    std::list<std::string> aliases;
    Utils::split_string(alias_hosts, ',', aliases, 0, true);
    stack_data.aliases.insert(aliases.begin(), aliases.end());
    for (std::unordered_set<std::string>::iterator it = stack_data.aliases.begin();
         it != stack_data.aliases.end();
         ++it)
    {
      pj_strdup2(stack_data.pool, &stack_data.name[stack_data.name_cnt], it->c_str());
      stack_data.name_cnt++;
    }
  }

  LOG_STATUS("Local host aliases:");
  for (i = 0; i < stack_data.name_cnt; ++i)
  {
    LOG_STATUS(" %.*s",
               (int)stack_data.name[i].slen,
               stack_data.name[i].ptr);
  }

  // Set up the Last Value Cache, accumulators and counters.
  std::string process_name;
  if ((stack_data.pcscf_trusted_port != 0) &&
      (stack_data.pcscf_untrusted_port != 0))
  {
    process_name = "bono";
  }
  else
  {
    process_name = "sprout";
  }

  stack_data.stats_aggregator = new LastValueCache(num_known_stats,
                                                   known_statnames,
                                                   process_name);

  if (quiescing_mgr_arg != NULL)
  {
    quiescing_mgr = quiescing_mgr_arg;

    // Create an instance of the stack quiesce handler. This acts as a glue
    // class between the stack modulem connections tracker, and the quiescing
    // manager.
    stack_quiesce_handler = new StackQuiesceHandler();

    // Create a new connection tracker, and register the quiesce handler with
    // it.
    connection_tracker = new ConnectionTracker(stack_quiesce_handler);

    // Register the quiesce handler with the quiescing manager (the former
    // implements the connection handling interface).
    quiescing_mgr->register_conns_handler(stack_quiesce_handler);

    pjsip_endpt_register_module(stack_data.endpt, &mod_connection_tracking);
  }

  return status;
}
Пример #20
0
static int arm11_resume(struct target *target, int current,
		uint32_t address, int handle_breakpoints, int debug_execution)
{
	//	  LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d",
	//	current, address, handle_breakpoints, debug_execution);

	struct arm11_common *arm11 = target_to_arm11(target);

	LOG_DEBUG("target->state: %s",
		target_state_name(target));


	if (target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	address = arm11_nextpc(arm11, current, address);

	LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");

	/* clear breakpoints/watchpoints and VCR*/
	arm11_sc7_clear_vbw(arm11);

	if (!debug_execution)
		target_free_all_working_areas(target);

	/* Should we skip over breakpoints matching the PC? */
	if (handle_breakpoints) {
		struct breakpoint *bp;

		for (bp = target->breakpoints; bp; bp = bp->next)
		{
			if (bp->address == address)
			{
				LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
				arm11_step(target, 1, 0, 0);
				break;
			}
		}
	}

	/* activate all breakpoints */
	if (true) {
		struct breakpoint *bp;
		unsigned brp_num = 0;

		for (bp = target->breakpoints; bp; bp = bp->next)
		{
			struct arm11_sc7_action	brp[2];

			brp[0].write	= 1;
			brp[0].address	= ARM11_SC7_BVR0 + brp_num;
			brp[0].value	= bp->address;
			brp[1].write	= 1;
			brp[1].address	= ARM11_SC7_BCR0 + brp_num;
			brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);

			arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp));

			LOG_DEBUG("Add BP %d at %08" PRIx32, brp_num,
					bp->address);

			brp_num++;
		}

		if (arm11_vcr)
			arm11_sc7_set_vcr(arm11, arm11_vcr);
	}

	/* activate all watchpoints and breakpoints */
	arm11_leave_debug_state(arm11, true);

	arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);

	CHECK_RETVAL(jtag_execute_queue());

	int i = 0;
	while (1)
	{
		CHECK_RETVAL(arm11_read_DSCR(arm11));

		LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr);

		if (arm11->dscr & DSCR_CORE_RESTARTED)
			break;


		long long then = 0;
		if (i == 1000)
		{
			then = timeval_ms();
		}
		if (i >= 1000)
		{
			if ((timeval_ms()-then) > 1000)
			{
				LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
				return ERROR_FAIL;
			}
		}
		i++;
	}

	target->debug_reason = DBG_REASON_NOTHALTED;
	if (!debug_execution)
		target->state = TARGET_RUNNING;
	else
		target->state = TARGET_DEBUG_RUNNING;
	CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));

	return ERROR_OK;
}
Пример #21
0
static int stmsmi_write(struct flash_bank *bank, uint8_t *buffer,
	uint32_t offset, uint32_t count)
{
	struct target *target = bank->target;
	struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;
	uint32_t io_base = stmsmi_info->io_base;
	uint32_t cur_count, page_size, page_offset;
	int sector;
	int retval = ERROR_OK;

	LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32,
		__FUNCTION__, offset, count);

	if (target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if (offset + count > stmsmi_info->dev->size_in_bytes)
	{
		LOG_WARNING("Write pasts end of flash. Extra data discarded.");
		count = stmsmi_info->dev->size_in_bytes - offset;
	}

	/* Check sector protection */
	for (sector = 0; sector < bank->num_sectors; sector++)
	{
		/* Start offset in or before this sector? */
		/* End offset in or behind this sector? */
		if ( (offset <
				(bank->sectors[sector].offset + bank->sectors[sector].size))
			&& ((offset + count - 1) >= bank->sectors[sector].offset)
			&& bank->sectors[sector].is_protected )
		{
			LOG_ERROR("Flash sector %d protected", sector);
			return ERROR_FAIL;
		}
	}

	page_size = stmsmi_info->dev->pagesize;

	/* unaligned buffer head */
	if (count > 0 && (offset & 3) != 0)
	{
		cur_count = 4 - (offset & 3);
		if (cur_count > count)
			cur_count = count;
		retval = smi_write_buffer(bank, buffer, bank->base + offset,
			cur_count);
		if (retval != ERROR_OK)
			goto err;
		offset += cur_count;
		buffer += cur_count;
		count -= cur_count;
	}

	page_offset = offset % page_size;
	/* central part, aligned words */
	while (count >= 4)
	{
		/* clip block at page boundary */
		if (page_offset + count > page_size)
			cur_count = page_size - page_offset;
		else
			cur_count = count & ~3;

		retval = smi_write_buffer(bank, buffer, bank->base + offset,
			cur_count);
		if (retval != ERROR_OK)
			goto err;

		page_offset = 0;
		buffer += cur_count;
		offset += cur_count;
		count -= cur_count;

		keep_alive();
	}

	/* buffer tail */
	if (count > 0)
		retval = smi_write_buffer(bank, buffer, bank->base + offset, count);

err:
	/* Switch to HW mode before return to prompt */
	SMI_SET_HW_MODE();
	return retval;
}
Пример #22
0
static int arm11_step(struct target *target, int current,
		uint32_t address, int handle_breakpoints)
{
	LOG_DEBUG("target->state: %s",
		target_state_name(target));

	if (target->state != TARGET_HALTED)
	{
		LOG_WARNING("target was not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	struct arm11_common *arm11 = target_to_arm11(target);

	address = arm11_nextpc(arm11, current, address);

	LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");


	/** \todo TODO: Thumb not supported here */

	uint32_t	next_instruction;

	CHECK_RETVAL(arm11_read_memory_word(arm11, address, &next_instruction));

	/* skip over BKPT */
	if ((next_instruction & 0xFFF00070) == 0xe1200070)
	{
		address = arm11_nextpc(arm11, 0, address + 4);
		LOG_DEBUG("Skipping BKPT");
	}
	/* skip over Wait for interrupt / Standby */
	/* mcr	15, 0, r?, cr7, cr0, {4} */
	else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90)
	{
		address = arm11_nextpc(arm11, 0, address + 4);
		LOG_DEBUG("Skipping WFI");
	}
	/* ignore B to self */
	else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
	{
		LOG_DEBUG("Not stepping jump to self");
	}
	else
	{
		/** \todo TODO: check if break-/watchpoints make any sense at all in combination
		* with this. */

		/** \todo TODO: check if disabling IRQs might be a good idea here. Alternatively
		* the VCR might be something worth looking into. */


		/* Set up breakpoint for stepping */

		struct arm11_sc7_action	brp[2];

		brp[0].write	= 1;
		brp[0].address	= ARM11_SC7_BVR0;
		brp[1].write	= 1;
		brp[1].address	= ARM11_SC7_BCR0;

		if (arm11_config_hardware_step)
		{
			/* Hardware single stepping ("instruction address
			 * mismatch") is used if enabled.  It's not quite
			 * exactly "run one instruction"; "branch to here"
			 * loops won't break, neither will some other cases,
			 * but it's probably the best default.
			 *
			 * Hardware single stepping isn't supported on v6
			 * debug modules.  ARM1176 and v7 can support it...
			 *
			 * FIXME Thumb stepping likely needs to use 0x03
			 * or 0xc0 byte masks, not 0x0f.
			 */
			 brp[0].value	= address;
			 brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5)
					| (0 << 14) | (0 << 16) | (0 << 20)
					| (2 << 21);
		} else
		{
			/* Sets a breakpoint on the next PC, as calculated
			 * by instruction set simulation.
			 *
			 * REVISIT stepping Thumb on ARM1156 requires Thumb2
			 * support from the simulator.
			 */
			uint32_t next_pc;
			int retval;

			retval = arm_simulate_step(target, &next_pc);
			if (retval != ERROR_OK)
				return retval;

			brp[0].value	= next_pc;
			brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5)
					| (0 << 14) | (0 << 16) | (0 << 20)
					| (0 << 21);
		}

		CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));

		/* resume */


		if (arm11_config_step_irq_enable)
			/* this disable should be redundant ... */
			arm11->dscr &= ~DSCR_INT_DIS;
		else
			arm11->dscr |= DSCR_INT_DIS;


		CHECK_RETVAL(arm11_leave_debug_state(arm11, handle_breakpoints));

		arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);

		CHECK_RETVAL(jtag_execute_queue());

		/* wait for halt */
		int i = 0;

		while (1)
		{
			const uint32_t mask = DSCR_CORE_RESTARTED
					| DSCR_CORE_HALTED;

			CHECK_RETVAL(arm11_read_DSCR(arm11));
			LOG_DEBUG("DSCR %08x e", (unsigned) arm11->dscr);

			if ((arm11->dscr & mask) == mask)
				break;

			long long then = 0;
			if (i == 1000)
			{
				then = timeval_ms();
			}
			if (i >= 1000)
			{
				if ((timeval_ms()-then) > 1000)
				{
					LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
					return ERROR_FAIL;
				}
			}
			i++;
		}

		/* clear breakpoint */
		arm11_sc7_clear_vbw(arm11);

		/* save state */
		CHECK_RETVAL(arm11_debug_entry(arm11));

		/* restore default state */
		arm11->dscr &= ~DSCR_INT_DIS;

	}

	target->debug_reason = DBG_REASON_SINGLESTEP;

	CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));

	return ERROR_OK;
}
OMX_STREAMING_PIPE_API CPresult HttpsPipe_Create(CPhandle *hContent, CPstring szURI)
{
    LOG_DEBUG("%s hContent %p\n", __FUNCTION__, hContent);
    return HttpsPipe_Open(hContent, szURI, CP_AccessRead);
}
Пример #24
0
/* target memory access
 * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
 * count: number of items of <size>
 *
 * arm11_config_memrw_no_increment - in the future we may want to be able
 * to read/write a range of data to a "port". a "port" is an action on
 * read memory address for some peripheral.
 */
static int arm11_read_memory_inner(struct target *target,
		uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer,
		bool arm11_config_memrw_no_increment)
{
	/** \todo TODO: check if buffer cast to uint32_t* and uint16_t* might cause alignment problems */
	int retval;

	if (target->state != TARGET_HALTED)
	{
		LOG_WARNING("target was not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);

	struct arm11_common *arm11 = target_to_arm11(target);

	retval = arm11_run_instr_data_prepare(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* MRC p14,0,r0,c0,c5,0 */
	retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
	if (retval != ERROR_OK)
		return retval;

	switch (size)
	{
	case 1:
		arm11->arm.core_cache->reg_list[1].dirty = true;

		for (size_t i = 0; i < count; i++)
		{
			/* ldrb    r1, [r0], #1 */
			/* ldrb    r1, [r0] */
			arm11_run_instr_no_data1(arm11,
					!arm11_config_memrw_no_increment ? 0xe4d01001 : 0xe5d01000);

			uint32_t res;
			/* MCR p14,0,R1,c0,c5,0 */
			arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);

			*buffer++ = res;
		}

		break;

	case 2:
		{
			arm11->arm.core_cache->reg_list[1].dirty = true;

			for (size_t i = 0; i < count; i++)
			{
				/* ldrh    r1, [r0], #2 */
				arm11_run_instr_no_data1(arm11,
					!arm11_config_memrw_no_increment ? 0xe0d010b2 : 0xe1d010b0);

				uint32_t res;

				/* MCR p14,0,R1,c0,c5,0 */
				arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);

				uint16_t svalue = res;
				memcpy(buffer + i * sizeof(uint16_t), &svalue, sizeof(uint16_t));
			}

			break;
		}

	case 4:
		{
		uint32_t instr = !arm11_config_memrw_no_increment ? 0xecb05e01 : 0xed905e00;
		/** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
		uint32_t *words = (uint32_t *)buffer;

		/* LDC p14,c5,[R0],#4 */
		/* LDC p14,c5,[R0] */
		arm11_run_instr_data_from_core(arm11, instr, words, count);
		break;
		}
	}

	return arm11_run_instr_data_finish(arm11);
}
/**
 * A thread that actually handles the unregistration request of the GUI
 * (internal use only). See rm_unregister_account() for details.
 * @param args the account ID is stored here
 * @return empty
 */
void *unregistration_thread(void *args) {
	int accountId;				// current account
	int pos;					// position of account status information
	int rc;						// return code
	int timeoutCtr;				// timeout counter for sipstack events

	// accountId is given:
	accountId = (int) args;

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "unregistration thread entered, "
			  "accountId: %d", accountId);

	// try to gain lock because we want exclusive responsibility for 
	// unregistering this account - also we want to write data:
	rc = pthread_mutex_lock(&accInfoLock);
	if (rc != 0) {
		// failed to gain lock, exit (fatal error)
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "mutex lock could not be"
				  "acquired, error: %d", rc);
		thread_terminated();
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "mutex lock acquired");

	// a registration/update thread should be active and have saved account
	// information - find position in array of it: 
	rc = find_acc_by_id(accountId, &pos);
	if (!rc) {
		// no registration/update thread active
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "account not in use");

		rc = go_show_user_event(accountId, "ERROR",
								"Error unregistering account",
								"Account is not in use.",
								"This account is already unregistered.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// unlock and exit:
		pthread_mutex_unlock(&accInfoLock);
		thread_terminated();
		return NULL;
	}
	// prevent race conditions because we have to release the lock after
	// setting doShutdown to 1:
	if (accInfos[pos].doShutdown || accInfos[pos].isShutdown) {
		// a second unregister thread was started just when we are trying to
		// shutdown the active registration thread
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "another thread is already "
				  "unregistering");
		rc = go_show_user_event(accountId, "ERROR",
								"Error unregistering account",
								"Already unregistering.",
								"It is currently tried to unregister this "
								"account.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// unlock and exit:
		pthread_mutex_unlock(&accInfoLock);
		thread_terminated();
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "account is in use");

	// shutdown registration/update thread:
	accInfos[pos].doShutdown = 1;

	// release lock to enable abnormal termination (otherwise a dead lock
	// might occur if registration thread is trying to shutdown in case of
	// an error while updating):
	rc = pthread_mutex_unlock(&accInfoLock);
	if (rc != 0) {
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "mutex lock could not be "
				  "released, error %d", rc);
		thread_terminated();
		return NULL;
	}

	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "wait for registration thread "
			  "to finish");

	// now wait on registration thread:
	// isShutdown == 1 means regular shutdown
	// accountId == -1 means the account status info was cleared because 
	// of an error
	while (!accInfos[pos].isShutdown && accInfos[pos].accountId != -1) {
		sched_yield();
		usleep(100000);			// 0.1 seconds
	}
	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "done waiting");

	// we should not send an unregister if account is not registered
	if (!accInfos[pos].isRegistered || accInfos[pos].accountId == -1) {
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "unregister failed: account "
				  "is not registered");
		rc = go_show_user_event(accountId, "ERROR",
								"Error unregistering account",
								"Account is not in use.",
								"This account is already unregistered.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// exit:
		thread_terminated();
		return NULL;
	}
	// tell dispatcher which OK is expected:
	accInfos[pos].eventArrived = 0;
	accInfos[pos].waitingOnUnregOK = 1;

	// send REGISTER with expire=0 to registrar:
	rc = sipstack_send_unregister(accInfos[pos].regId);
	if (!rc) {
		// sending REGISTER failed
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "send unregister failed");
		rc = go_show_user_event(accountId, "ERROR",
								"Error unregistering account",
								"Sending unregistration message failed.",
								"Failed to send your unregistration "
								"request to the given registrar."
								"Please check whether your account "
								"data is correct and whether your "
								"internet connection is working "
								"correctly.");
		if (!rc) {
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "failed to inform the GUI");
		}
		// exit:
		thread_terminated();
		return NULL;
	}
	// now wait on response:
	timeoutCtr = 0;
	while (!accInfos[pos].eventArrived) {
		sched_yield();
		usleep(100000);			// 0.1 seconds
		timeoutCtr++;
		if (timeoutCtr ==
			config.core.sipOutput.registrarManager.timeout * 10) {
			break;
		}
	}
	LOG_DEBUG(REGISTRAR_MGR_MSG_PREFIX "done waiting");

	// clear flags:
	accInfos[pos].eventArrived = 0;
	accInfos[pos].waitingOnUnregOK = 0;

	// test if account is really unregistered:
	if (accInfos[pos].isRegistered) {
		// account is still in use:
		LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "unregister failed: account "
				  "is still registered");
		if (accInfos[pos].informGui) {
			rc = go_show_user_event(accountId, "ERROR",
									"Error unregistering account",
									"Sending unregistration message failed.",
									"Failed to send your unregistration "
									"request to the given registrar."
									"Please check whether your account "
									"data is correct and whether your "
									"internet connection is working "
									"correctly.");
			if (!rc) {
				LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX
						  "failed to inform the GUI");
			}
		}
		// don't terminate because there is no point in believing the account 
		// was still registered with the registrar
	}

	if (accInfos[pos].informGui) {
		// inform GUI that unregister succeeded:
		rc = go_change_reg_status(accountId, 0);
		if (!rc) {
			// failed to contact GUI
			LOG_ERROR(REGISTRAR_MGR_MSG_PREFIX "GUI registration status "
					  "update failed");

			// exit:
			thread_terminated();
			return NULL;
		}
	}
	// mark account as no longer used:
	clear_account_info(pos);

	LOG_INFO(REGISTRAR_MGR_MSG_PREFIX
			 "unregister of account %d succeeded", accountId);

	// we are done:
	thread_terminated();
	return NULL;
}
Пример #26
0
/*
* no_increment - in the future we may want to be able
* to read/write a range of data to a "port". a "port" is an action on
* read memory address for some peripheral.
*/
static int arm11_write_memory_inner(struct target *target,
		uint32_t address, uint32_t size,
		uint32_t count, uint8_t *buffer,
		bool no_increment)
{
	int retval;

	if (target->state != TARGET_HALTED)
	{
		LOG_WARNING("target was not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);

	struct arm11_common *arm11 = target_to_arm11(target);

	retval = arm11_run_instr_data_prepare(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* load r0 with buffer address */
	/* MRC p14,0,r0,c0,c5,0 */
	retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
	if (retval != ERROR_OK)
		return retval;

	/* burst writes are not used for single words as those may well be
	 * reset init script writes.
	 *
	 * The other advantage is that as burst writes are default, we'll
	 * now exercise both burst and non-burst code paths with the
	 * default settings, increasing code coverage.
	 */
	bool burst = arm11_config_memwrite_burst && (count > 1);

	switch (size)
	{
	case 1:
		{
			arm11->arm.core_cache->reg_list[1].dirty = true;

			for (size_t i = 0; i < count; i++)
			{
				/* load r1 from DCC with byte data */
				/* MRC p14,0,r1,c0,c5,0 */
				retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
				if (retval != ERROR_OK)
					return retval;

				/* write r1 to memory */
				/* strb    r1, [r0], #1 */
				/* strb    r1, [r0] */
				retval = arm11_run_instr_no_data1(arm11,
					!no_increment
						? 0xe4c01001
						: 0xe5c01000);
				if (retval != ERROR_OK)
					return retval;
			}

			break;
		}

	case 2:
		{
			arm11->arm.core_cache->reg_list[1].dirty = true;

			for (size_t i = 0; i < count; i++)
			{
				uint16_t value;
				memcpy(&value, buffer + i * sizeof(uint16_t), sizeof(uint16_t));

				/* load r1 from DCC with halfword data */
				/* MRC p14,0,r1,c0,c5,0 */
				retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, value);
				if (retval != ERROR_OK)
					return retval;

				/* write r1 to memory */
				/* strh    r1, [r0], #2 */
				/* strh    r1, [r0] */
				retval = arm11_run_instr_no_data1(arm11,
					!no_increment
						? 0xe0c010b2
						: 0xe1c010b0);
				if (retval != ERROR_OK)
					return retval;
			}

			break;
		}

	case 4: {
		/* stream word data through DCC directly to memory */
		/* increment:		STC p14,c5,[R0],#4 */
		/* no increment:	STC p14,c5,[R0]*/
		uint32_t instr = !no_increment ? 0xeca05e01 : 0xed805e00;

		/** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
		uint32_t *words = (uint32_t*)buffer;

		/* "burst" here just means trusting each instruction executes
		 * fully before we run the next one:  per-word roundtrips, to
		 * check the Ready flag, are not used.
		 */
		if (!burst)
			retval = arm11_run_instr_data_to_core(arm11,
					instr, words, count);
		else
			retval = arm11_run_instr_data_to_core_noack(arm11,
					instr, words, count);
		if (retval != ERROR_OK)
			return retval;

		break;
	}
	}

	/* r0 verification */
	if (!no_increment)
	{
		uint32_t r0;

		/* MCR p14,0,R0,c0,c5,0 */
		retval = arm11_run_instr_data_from_core(arm11, 0xEE000E15, &r0, 1);
		if (retval != ERROR_OK)
			return retval;

		if (address + size * count != r0)
		{
			LOG_ERROR("Data transfer failed. Expected end "
					"address 0x%08x, got 0x%08x",
					(unsigned) (address + size * count),
					(unsigned) r0);

			if (burst)
				LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode");

			if (arm11_config_memwrite_error_fatal)
				return ERROR_FAIL;
		}
	}

	return arm11_run_instr_data_finish(arm11);
}
Пример #27
0
static int lpcspifi_erase(struct flash_bank *bank, int first, int last)
{
	struct target *target = bank->target;
	struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
	struct reg_param reg_params[4];
	struct armv7m_algorithm armv7m_info;
	struct working_area *erase_algorithm;
	int retval = ERROR_OK;
	int sector;

	LOG_DEBUG("erase from sector %d to sector %d", first, last);

	if (target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if ((first < 0) || (last < first) || (last >= bank->num_sectors)) {
		LOG_ERROR("Flash sector invalid");
		return ERROR_FLASH_SECTOR_INVALID;
	}

	if (!(lpcspifi_info->probed)) {
		LOG_ERROR("Flash bank not probed");
		return ERROR_FLASH_BANK_NOT_PROBED;
	}

	for (sector = first; sector <= last; sector++) {
		if (bank->sectors[sector].is_protected) {
			LOG_ERROR("Flash sector %d protected", sector);
			return ERROR_FAIL;
		}
	}

	/* If we're erasing the entire chip and the flash supports
	 * it, use a bulk erase instead of going sector-by-sector. */
	if (first == 0 && last == (bank->num_sectors - 1)
		&& lpcspifi_info->dev->chip_erase_cmd != lpcspifi_info->dev->erase_cmd) {
		LOG_DEBUG("Chip supports the bulk erase command."\
		" Will use bulk erase instead of sector-by-sector erase.");
		retval = lpcspifi_bulk_erase(bank);

		if (retval == ERROR_OK) {
			retval = lpcspifi_set_hw_mode(bank);
			return retval;
		} else
			LOG_WARNING("Bulk flash erase failed. Falling back to sector-by-sector erase.");
	}

	retval = lpcspifi_set_hw_mode(bank);
	if (retval != ERROR_OK)
		return retval;

	/* see contrib/loaders/flash/lpcspifi_erase.S for src */
	static const uint8_t lpcspifi_flash_erase_code[] = {
		0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
		0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
		0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
		0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
		0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
		0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
		0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
		0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
		0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
		0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
		0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
		0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
		0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
		0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
		0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
		0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
		0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
		0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
		0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
		0x00, 0xf0, 0x52, 0xf8, 0x4f, 0xf0, 0x06, 0x09,
		0x00, 0xf0, 0x3b, 0xf8, 0x00, 0xf0, 0x48, 0xf8,
		0x00, 0xf0, 0x4a, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
		0x00, 0xf0, 0x33, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
		0x00, 0xf0, 0x2f, 0xf8, 0x00, 0xf0, 0x3c, 0xf8,
		0x19, 0xf0, 0x02, 0x0f, 0x00, 0xf0, 0x45, 0x80,
		0x00, 0xf0, 0x3a, 0xf8, 0x4f, 0xea, 0x02, 0x09,
		0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xea, 0x10, 0x49,
		0x00, 0xf0, 0x1f, 0xf8, 0x4f, 0xea, 0x10, 0x29,
		0x00, 0xf0, 0x1b, 0xf8, 0x4f, 0xea, 0x00, 0x09,
		0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, 0x24, 0xf8,
		0x00, 0xf0, 0x26, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
		0x00, 0xf0, 0x0f, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
		0x00, 0xf0, 0x0b, 0xf8, 0x00, 0xf0, 0x18, 0xf8,
		0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4, 0xf0, 0xaf,
		0x01, 0x39, 0xf9, 0xb1, 0x18, 0x44, 0xff, 0xf7,
		0xbf, 0xbf, 0x4f, 0xf4, 0x40, 0x5a, 0xc4, 0xf2,
		0x08, 0x0a, 0xca, 0xf8, 0x08, 0x90, 0xda, 0xf8,
		0x0c, 0x90, 0x19, 0xf0, 0x10, 0x0f, 0x7f, 0xf4,
		0xfa, 0xaf, 0xda, 0xf8, 0x08, 0x90, 0x70, 0x47,
		0x4f, 0xf0, 0xff, 0x08, 0x00, 0xf0, 0x02, 0xb8,
		0x4f, 0xf0, 0x00, 0x08, 0x4f, 0xf4, 0x80, 0x4a,
		0xc4, 0xf2, 0x0f, 0x0a, 0xca, 0xf8, 0xab, 0x80,
		0x70, 0x47, 0x00, 0x20, 0x00, 0xbe, 0xff, 0xff
	};

	armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
	armv7m_info.core_mode = ARM_MODE_THREAD;


	/* Get memory for spifi initialization algorithm */
	retval = target_alloc_working_area(target, sizeof(lpcspifi_flash_erase_code),
		&erase_algorithm);
	if (retval != ERROR_OK) {
		LOG_ERROR("Insufficient working area. You must configure a working"\
			" area of at least %zdB in order to erase SPIFI flash.",
			sizeof(lpcspifi_flash_erase_code));
		return retval;
	}

	/* Write algorithm to working area */
	retval = target_write_buffer(target, erase_algorithm->address,
		sizeof(lpcspifi_flash_erase_code), lpcspifi_flash_erase_code);
	if (retval != ERROR_OK) {
		target_free_working_area(target, erase_algorithm);
		return retval;
	}

	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);	/* Start address */
	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);	/* Sector count */
	init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);	/* Erase command */
	init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);	/* Sector size */

	buf_set_u32(reg_params[0].value, 0, 32, bank->sectors[first].offset);
	buf_set_u32(reg_params[1].value, 0, 32, last - first + 1);
	buf_set_u32(reg_params[2].value, 0, 32, lpcspifi_info->dev->erase_cmd);
	buf_set_u32(reg_params[3].value, 0, 32, bank->sectors[first].size);

	/* Run the algorithm */
	retval = target_run_algorithm(target, 0 , NULL, 4, reg_params,
		erase_algorithm->address,
		erase_algorithm->address + sizeof(lpcspifi_flash_erase_code) - 4,
		3000*(last - first + 1), &armv7m_info);

	if (retval != ERROR_OK)
		LOG_ERROR("Error executing flash erase algorithm");

	target_free_working_area(target, erase_algorithm);

	destroy_reg_param(&reg_params[0]);
	destroy_reg_param(&reg_params[1]);
	destroy_reg_param(&reg_params[2]);
	destroy_reg_param(&reg_params[3]);

	retval = lpcspifi_set_hw_mode(bank);

	return retval;
}
Пример #28
0
void
tools_snag_brush_handler (
	int mouse_event,
	int mouse_buttons,
	int keyhit,
	int x,
	int y
)
{
    static int startx;
    static int starty;

    switch (mouse_event)
    {
	case (TOOL_EVENT_INIT):
	    CURSOR_CROSSHAIRS();
	    Page_Negative(page_rubberband);
	    LOG_DEBUG("brush");
	    startx = x;
	    starty = y;
            jsui_dialog_tell_message( toolbar_dialog, 
                        TOOLBAR_SNAGBRUSH, JSUI_MSG_TRIGGER_L );
	    break;

	case (TOOL_EVENT_DEINIT):
	    Page_Negative(page_rubberband);
	    break;

	case (TOOL_EVENT_STARTDOWN):
	    startx = x;
	    starty = y;
	    break;

	case (TOOL_EVENT_DRAGGING):
	case (TOOL_EVENT_DRAG_STAT):
	    Page_Negative(page_rubberband);
	    if (mouse_buttons == 1)
	    {
		primitive_rectangle_hollow(page_rubberband, pen_cycle,
			primitive_pixel, startx, starty, x, y);

	    }
	    else if (mouse_buttons == 3)
	    {
		primitive_rectangle_hollow(page_rubberband, pen_cycle,
			primitive_pixel, startx, starty, x, y);
	    }
	    break;

	case (TOOL_EVENT_RELEASE):
	    Page_Negative(page_rubberband);
/*
	    printf ("Snag brush:  (%d,%d) - (%d,%d)  %d %d\n", 
			x, y, startx, starty, 
			ABS(x-startx), ABS(y-starty));
*/
	    LOG_DEBUG( "snag brush" );

            if (brush_custom)  Page_Destroy(brush_custom);

	    brush_custom = Page_Cutout_Brush(
				page_active, startx, starty, x, y,
				excl_brush, 
				(mouse_buttons == 3)?page_active->bgpen:NULL);

	    brush_active = brush_custom;
				
	    jsui_dialog_broadcast(PAINT_MSG_DOTTEDDRAW, 0);
	    jsui_dialog_broadcast(PAINT_MSG_MODEMATTE, 0);
	    drawing_mode = DRAW_STYLE_MATTE;
	    break;


	case (TOOL_EVENT_IDLE):
	    Page_Negative(page_rubberband);
	    primitive_crosshairs(page_rubberband, x, y);
	    break;

	case (TOOL_EVENT_NONE):
	default:
	    break;

    }
}
Пример #29
0
/* On exit, SW mode is kept */
static int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id)
{
	struct target *target = bank->target;
	struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
	uint32_t ssp_base = lpcspifi_info->ssp_base;
	uint32_t io_base = lpcspifi_info->io_base;
	uint32_t value;
	uint8_t id_buf[3] = {0, 0, 0};
	int retval;

	if (target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	LOG_DEBUG("Getting ID");
	retval = lpcspifi_set_sw_mode(bank);
	if (retval != ERROR_OK)
		return retval;

	/* poll WIP */
	if (retval == ERROR_OK)
		retval = wait_till_ready(bank, SSP_PROBE_TIMEOUT);

	/* Send SPI command "read ID" */
	if (retval == ERROR_OK)
		retval = ssp_setcs(target, io_base, 0);
	if (retval == ERROR_OK)
		retval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_READ_ID);
	if (retval == ERROR_OK)
		retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
	if (retval == ERROR_OK)
		retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);

	/* Dummy write to clock in data */
	if (retval == ERROR_OK)
		retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
	if (retval == ERROR_OK)
		retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
	if (retval == ERROR_OK)
		retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
	if (retval == ERROR_OK)
		id_buf[0] = value;

	/* Dummy write to clock in data */
	if (retval == ERROR_OK)
		retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
	if (retval == ERROR_OK)
		retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
	if (retval == ERROR_OK)
		retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
	if (retval == ERROR_OK)
		id_buf[1] = value;

	/* Dummy write to clock in data */
	if (retval == ERROR_OK)
		retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
	if (retval == ERROR_OK)
		retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
	if (retval == ERROR_OK)
		retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
	if (retval == ERROR_OK)
		id_buf[2] = value;

	if (retval == ERROR_OK)
		retval = ssp_setcs(target, io_base, 1);
	if (retval == ERROR_OK)
		*id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0];

	return retval;
}
Пример #30
0
HTTPCode AuthTimeoutTask::handle_response(std::string body)
{
  Json::Value json_body;
  std::string json_str = body;
  Json::Reader reader;
  bool parsingSuccessful = reader.parse(json_str.c_str(), json_body);

  if (!parsingSuccessful)
  {
    LOG_ERROR("Failed to read opaque data, %s",
              reader.getFormattedErrorMessages().c_str());
    return HTTP_BAD_REQUEST;
  }

  if ((json_body.isMember("impu")) &&
      ((json_body)["impu"].isString()))
  {
    _impu = json_body.get("impu", "").asString();
    report_sip_all_register_marker(trail(), _impu);
  }
  else
  {
    LOG_ERROR("IMPU not available in JSON");
    return HTTP_BAD_REQUEST;
  }

  if ((json_body.isMember("impi")) &&
      ((json_body)["impi"].isString()))
  {
    _impi = json_body.get("impi", "").asString();
  }
  else
  {
    LOG_ERROR("IMPI not available in JSON");
    return HTTP_BAD_REQUEST;
  }

  if ((json_body.isMember("nonce")) &&
      ((json_body)["nonce"].isString()))
  {
    _nonce = json_body.get("nonce", "").asString();
  }
  else
  {
    LOG_ERROR("Nonce not available in JSON");
    return HTTP_BAD_REQUEST;
  }

  bool success = false;
  uint64_t cas;
  Json::Value* av = _cfg->_avstore->get_av(_impi, _nonce, cas, trail());
  if (av != NULL)
  {
    // Use the original REGISTER's branch parameter for SAS
    // correlation

    correlate_branch_from_av(av, trail());

    // If authentication completed, we'll have written a marker to
    // indicate that. Look for it.
    if (!av->isMember("tombstone"))
    {
      LOG_DEBUG("AV for %s:%s has timed out", _impi.c_str(), _nonce.c_str());

      // The AUTHENTICATION_TIMEOUT SAR is idempotent, so there's no
      // problem if Chronos' timer pops twice (e.g. if we have high
      // latency and these operations take more than 2 seconds).

      // If either of these operations fail, we return a 500 Internal
      // Server Error - this will trigger Chronos to try a different
      // Sprout, which may have better connectivity to Homestead or Memcached.
      HTTPCode hss_query = _cfg->_hss->update_registration_state(_impu, _impi, HSSConnection::AUTH_TIMEOUT, trail());

      if (hss_query == HTTP_OK)
      {
        success = true;
      }
    }
    else
    {
      SAS::Event event(trail(), SASEvent::AUTHENTICATION_TIMER_POP_IGNORED, 0);
      SAS::report_event(event);

      LOG_DEBUG("Tombstone record indicates Authentication Vector has been used successfully - ignoring timer pop");
      success = true;
    }
  }
  else
  {
    LOG_WARNING("Could not find AV for %s:%s when checking authentication timeout", _impi.c_str(), _nonce.c_str()); // LCOV_EXCL_LINE
  }
  delete av;

  return success ? HTTP_OK : HTTP_SERVER_ERROR;
}