Пример #1
0
static struct att_send_op *create_att_send_op(struct bt_att *att,
						uint8_t opcode,
						const void *pdu,
						uint16_t length,
						bt_att_response_func_t callback,
						void *user_data,
						bt_att_destroy_func_t destroy)
{
	struct att_send_op *op;
	enum att_op_type op_type;

	if (length && !pdu)
		return NULL;

	op_type = get_op_type(opcode);
	if (op_type == ATT_OP_TYPE_UNKNOWN)
		return NULL;

	/* If the opcode corresponds to an operation type that does not elicit a
	 * response from the remote end, then no callback should have been
	 * provided, since it will never be called.
	 */
	if (callback && op_type != ATT_OP_TYPE_REQ && op_type != ATT_OP_TYPE_IND)
		return NULL;

	/* Similarly, if the operation does elicit a response then a callback
	 * must be provided.
	 */
	if (!callback && (op_type == ATT_OP_TYPE_REQ || op_type == ATT_OP_TYPE_IND))
		return NULL;

	op = new0(struct att_send_op, 1);
	if (!op)
		return NULL;

	op->type = op_type;
	op->opcode = opcode;
	op->callback = callback;
	op->destroy = destroy;
	op->user_data = user_data;

	if (!encode_pdu(att, op, pdu, length)) {
		free(op);
		return NULL;
	}

	return op;
}
Пример #2
0
static void handle_notify(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
								ssize_t pdu_len)
{
	const struct queue_entry *entry;
	bool found;

	if ((opcode & ATT_OP_SIGNED_MASK) && !att->crypto) {
		if (!handle_signed(att, opcode, pdu, pdu_len))
			return;
		pdu_len -= BT_ATT_SIGNATURE_LEN;
	}

	bt_att_ref(att);

	found = false;
	entry = queue_get_entries(att->notify_list);

	while (entry) {
		struct att_notify *notify = entry->data;

		entry = entry->next;

		if (!opcode_match(notify->opcode, opcode))
			continue;

		found = true;

		if (notify->callback)
			notify->callback(opcode, pdu, pdu_len,
							notify->user_data);

		/* callback could remove all entries from notify list */
		if (queue_isempty(att->notify_list))
			break;
	}

	/*
	 * If this was a request and no handler was registered for it, respond
	 * with "Not Supported"
	 */
	if (!found && get_op_type(opcode) == ATT_OP_TYPE_REQ)
		respond_not_supported(att, opcode);

	bt_att_unref(att);
}
Пример #3
0
static bool can_read_data(struct io *io, void *user_data)
{
	struct bt_att *att = user_data;
	uint8_t opcode;
	uint8_t *pdu;
	ssize_t bytes_read;

	bytes_read = read(att->fd, att->buf, att->mtu);
	if (bytes_read < 0)
		return false;

	util_hexdump('>', att->buf, bytes_read,
					att->debug_callback, att->debug_data);

	if (bytes_read < ATT_MIN_PDU_LEN)
		return true;

	pdu = att->buf;
	opcode = pdu[0];

	/* Act on the received PDU based on the opcode type */
	switch (get_op_type(opcode)) {
	case ATT_OP_TYPE_RSP:
		util_debug(att->debug_callback, att->debug_data,
				"ATT response received: 0x%02x", opcode);
		handle_rsp(att, opcode, pdu + 1, bytes_read - 1);
		break;
	case ATT_OP_TYPE_CONF:
		util_debug(att->debug_callback, att->debug_data,
				"ATT opcode cannot be handled: 0x%02x", opcode);
		break;
	default:
		/* For all other opcodes notify the upper layer of the PDU and
		 * let them act on it.
		 */
		util_debug(att->debug_callback, att->debug_data,
					"ATT PDU received: 0x%02x", opcode);
		handle_notify(att, opcode, pdu + 1, bytes_read - 1);
		break;
	}

	return true;
}
Пример #4
0
void Tokenizer::handle_char(char new_ch) {
    // Checks for token ending conditions and buffer tasks for each possible state.

    switch (current_state) {
    case 0: // ----- DEFAULT STATE
        // Buffer is now ready for character
        buffer_ready = true;
        return;

    case 1: // ----- WORD
        // Close word token on any non-alphanumeric character
        if (!isalpha(new_ch) && !isnumber(new_ch)) {
            // Determine token type and create token
            std::string type = get_word_type(token_buffer);
            create_token(type);
            // Open buffer to read incoming character
            buffer_ready = true;
        } else {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
        }
        break;

    case 2: // ----- NUMBER
        // Close number token on anything non-numerical
        if (!isnumber(new_ch)) {
            if (isalpha(new_ch)) {
                // ERROR
                // !!
            } else {
                // Create NUMBER token
                create_token("NUMBER");
                // Open buffer to read incoming character
                buffer_ready = true;
            }
        } else {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
        }
        break;

    case 3: // ----- STRING
        // Close string when a " is reached
        if (new_ch == '\"') {
            // Add last quotation mark to token
            token_buffer+=new_ch;
            // Keep buffer closed from handling incoming character
            current_state = 0;
            // Create STRING token
            create_token("STRING");
        } else {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
        }
        break;

    case 4: // ----- COMMENT
        // Close comment on a newline
        if (new_ch == '\r' || new_ch == '\n') {
            // Ready to read tokens again
            buffer_ready = true;
        }
        // Otherwise, do nothing until comment ends
        break;

    case 5: // ----- ! EXC
        // Could be a NOT or a RELOP
        if (new_ch == '=') {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
            // Keep buffer closed from handling incoming character
            current_state = 0;
            // Create a RELOP token
            create_token("RELOP");
        } else {
            // Create a NOT token
            create_token("NOT");
            // Open buffer to read incoming character
            buffer_ready = true;
        }
        break;

    case 6: // ----- = EQUALS
        // Check for second '='
        if (new_ch == '=') {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
            // Keep buffer closed from handling incoming character
            current_state = 0;
            // Create RELOP token
            create_token("RELOP");
        } else {
            // Without the second '=', it's an error
            create_token("ERROR");
            // Open buffer to read incoming character
            buffer_ready = true;
        }
        break;

    case 7: // ----- > GT
        // Could be a > or a >=
        if (new_ch == '=') {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
            // Keep buffer closed from handling incoming character
            current_state = 0;
            // Create RELOP token
            create_token("RELOP");
        } else {
            // Create '>' token
            create_token("RELOP");
            // Open buffer to read incoming character
            buffer_ready = true;
        }
        break;

    case 8: // ----- < LT
        // Could be a < or a <= or an ASSIGNOP
        if (new_ch == '-') {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
            // Keep buffer closed from handling incoming character
            current_state = 0;
            // Create ASSIGNOP token
            create_token("ASSIGNOP");
        } else if (new_ch == '=') {
            // Add incoming character to token buffer
            token_buffer+=new_ch;
            // Keep buffer closed from handling incoming character
            current_state = 0;
            // Create RELOP token
            create_token("RELOP");
        } else {
            // Create '<' token
            create_token("RELOP");
            // Open buffer to read incoming character
            buffer_ready = true;
        }
        break;

    case 10: // ----- Unambiguous single character
        // Create token immediately
        std::string type = get_op_type(token_buffer[0]);
        create_token(type);
        // Open buffer to read incoming character
        buffer_ready = true;
        break;

    }
}
Пример #5
0
static bool can_read_data(struct io *io, void *user_data)
{
	struct bt_att *att = user_data;
	uint8_t opcode;
	uint8_t *pdu;
	ssize_t bytes_read;

	bytes_read = read(att->fd, att->buf, att->mtu);
	if (bytes_read < 0)
		return false;

	util_hexdump('>', att->buf, bytes_read,
					att->debug_callback, att->debug_data);

	if (bytes_read < ATT_MIN_PDU_LEN)
		return true;

	pdu = att->buf;
	opcode = pdu[0];

	bt_att_ref(att);

	/* Act on the received PDU based on the opcode type */
	switch (get_op_type(opcode)) {
	case ATT_OP_TYPE_RSP:
		util_debug(att->debug_callback, att->debug_data,
				"ATT response received: 0x%02x", opcode);
		handle_rsp(att, opcode, pdu + 1, bytes_read - 1);
		break;
	case ATT_OP_TYPE_CONF:
		util_debug(att->debug_callback, att->debug_data,
				"ATT confirmation received: 0x%02x", opcode);
		handle_conf(att, pdu + 1, bytes_read - 1);
		break;
	case ATT_OP_TYPE_REQ:
		/*
		 * If a request is currently pending, then the sequential
		 * protocol was violated. Disconnect the bearer, which will
		 * promptly notify the upper layer via disconnect handlers.
		 */
		if (att->in_req) {
			util_debug(att->debug_callback, att->debug_data,
					"Received request while another is "
					"pending: 0x%02x", opcode);
			io_shutdown(att->io);
			bt_att_unref(att);

			return false;
		}

		att->in_req = true;

		/* Fall through to the next case */
	case ATT_OP_TYPE_CMD:
	case ATT_OP_TYPE_NOT:
	case ATT_OP_TYPE_UNKNOWN:
	case ATT_OP_TYPE_IND:
	default:
		/* For all other opcodes notify the upper layer of the PDU and
		 * let them act on it.
		 */
		util_debug(att->debug_callback, att->debug_data,
					"ATT PDU received: 0x%02x", opcode);
		handle_notify(att, opcode, pdu + 1, bytes_read - 1);
		break;
	}

	bt_att_unref(att);

	return true;
}
Пример #6
0
/* EOS = END OF STATEMENT */
void outputnode(tStatementNode * node, int EOS)
{

    int i=0;
    debugf("OUTPUT NODE = %s\n", node->type.str);
    if (func_is_defined(node->type.str, _func) || func_is_defined(node->type.str, _proc))
    {
        fprintf(out, "%s(", node->type.str);
        for (i=0; i<node->acount; i++)
        {
            debugf("param %d of %s is %s\n", i, node->type.str, node->args[i]->type.str);
            outputnode(node->args[i],  0);
            if (i+1 < node->acount)
                fprintf(out, ", ");
        }
        fprintf(out, ")", node->type.str);
    }
    else if (node->type.TT == BEGIN)
    {
        fprintf(out, "{\n");
        gen_code_func(node->thread);
        fprintf(out, "\n}\n");
    }
    else if (node->type.TT == IF || node->type.TT == ELIF || node->type.TT == ELSE)
    {

        fprintf(out, "%s", get_token_str(node->type));
        /* <ifstatement> ::= <if>"(" <condition> ")" "{" <instruction> "}"
                           | <ifstatement> <else if>"(" <condition> ")" "{" <instruction> "}"
                           | <else> "{" <instruction> "}"
        */
        if (node->type.TT != ELSE)
        {
            fprintf(out, " ( ");
            outputnode(node->condition,  0);
            fprintf(out, " ) ");
        }

        fprintf(out, "\n{\n");
        EOS = 0;
        gen_code_func(node->thread);
        fprintf(out, "}\n");
    }
    else if (node->type.TT == FOR)
    {
        fprintf(out, "for(");
        outputnode(node->from, 0);
        fprintf(out, ";");
        outputnode(node->from->left, 0);
        fprintf(out, "!=");
        outputnode(node->to, 0);
        fprintf(out, ";");
        fprintf(out, "%s ++)\n{\n", node->from->left->type.str);
        gen_code_func(node->thread);
        fprintf(out, "}\n");
    }
    else if (node->type.TT == WHILE)
    {
        fprintf(out, "while (");
        outputnode(node->condition, 0);
        fprintf(out, ")\n{\n");
        gen_code_func(node->thread);
        fprintf(out, "}\n");
    }
    else if (node->type.TT == REPEAT)
    {
        fprintf(out, "do {\n");
        gen_code_func(node->thread);
        fprintf(out, "}\n");
        fprintf(out, "while(!(");
        outputnode(node->condition, 0);
        fprintf(out, "));\n");
    }
    else if (node->type.TT == RETURN)
    {
        fprintf(out, "return ");
        if(node->unary!=NULL)
            outputnode(node->unary, 0);
        //fprintf(out, "");
    }
    else if (node->type.TT == BREAK || node->type.TT == CONTINUE)
    {
        fprintf(out, node->type.str);
    }
    else if (token_is_op(node->type))
    {
        debugf("[codegen]: node %s is operation.\n", node->type.str);
        fprintf(out, "(");
        if (op_is_unary(node->type) && (node->left == NULL))
        {
            debugf("[codegen]: op %s is unary\n", node->type.str);
            fprintf(out, " %s ", get_token_str(node->type));
            outputnode(node->unary, 0);
        }
        else
        {
            /* special tokens, like index ":" or addintion for string, or string multiplication, etc ... */
            if(node->type.TT == ':')
            {
                outputnode(node->left,  0);
                fprintf(out, " [ ");
                outputnode(node->right,  0);
                fprintf(out, " ] ");
            }

            else if(node->type.TT == '+')
            {
                if(strcmp(get_op_type(node->left, node->parent_thread), "str") == 0)
                {
                    // Right token is automatically a string

                    fprintf(out, "addstr(");
                    outputnode(node->left,  0);
                    fprintf(out, ", ");
                    outputnode(node->right,  0);
                    fprintf(out, ")");
                }
                else
                {
                    outputnode(node->left,  0);
                    fprintf(out, " %s ", get_token_str(node->type));
                    outputnode(node->right,  0);
                }
            }
            else if (node->type.TT == '*')
            {
                int left_is_string = (strcmp(get_op_type(node->left, node->parent_thread), "str") == 0);
                if ((left_is_string) ||
                        (strcmp(get_op_type(node->right, node->parent_thread), "str") == 0))
                {
                    //check which node is the string:
                    fprintf(out, "repstr(");

                    if(left_is_string)
                    {
                        outputnode(node->left,  0);
                        fprintf(out, ", ");
                        outputnode(node->right,  0);
                    }
                    else
                    {
                        outputnode(node->right,  0);
                        fprintf(out, ", ");
                        outputnode(node->left,  0);
                    }

                    fprintf(out, ")");
                }
                else
                {
                    outputnode(node->left,  0);
                    fprintf(out, " %s ", get_token_str(node->type));
                    outputnode(node->right,  0);
                }
            }
            else if ((node->type.TT == '.')|| (node->type.TT == DYN_CALL))
            {
                debugf("output class = %d", node->right->member_func);
                if(node->right->member_func == 0)
                {
                    // get mode
                    tType type = find_type(get_op_type(node->left, node->parent_thread));
                    if (node->type.TT == DYN_CALL)
                        type = find_type(type.pointerto);

                    int p = is_member_data(node->right->type.str, &type.class_info);

                    tVar my_var = type.class_info.variables[p];

                    if (node->parent_thread->parent_class != NULL)
                        my_var.is_property = 0;

                    if ((my_var.is_property == 1) && (my_var.reads = NULL))
                    {
                        if (node->type.TT == '.')
                            fprintf(out, "%s (&", my_var.reads->gen_name);
                        else
                            fprintf(out, "%s (", my_var.reads->gen_name);
                        outputnode(node->left, 0);
                        fprintf(out, ")");
                    }
                    else
                    {
                        outputnode(node->left,  0);
                        if (node->type.TT == '.')
                            fprintf(out, " . ");
                        else
                            fprintf(out, " -> ");
                        outputnode(node->right,  0);
                    }
                }
                else
                {

                    fprintf(out, "%s (", node->right->gen_name);
                    if(var_is_defined(node->left->type.str, node->parent_thread, 1))
                    {
                        fprintf(out, "&%s", node->left->type.str);
                    }
                    else
                    {
                        if (node->type.TT == '.')
                            fprintf(out, " & ");
                        outputnode(node->left, 0);
                    }

                    debugf("out %d\n", node->right->acount);

                    if(node->right->acount>0)
                        fprintf(out, ", ");
                    for (i=0; i<node->right->acount; i++)
                    {
                        outputnode(node->right->args[i],  0);
                        if (node->right->acount != i+1)
                            fprintf(out, ", ");
                    }
                    fprintf(out, ")");
                }
            }
            else
            {
                tType type = find_type(get_op_type(node->left->left, node->parent_thread));
                debugf("type %d name %s left is %s\n", type.type_kind, type.name, node->left->left->type.str);
                int p = -1;
                tVar my_var;
                my_var.is_property = 0;
                my_var.writes = NULL;
                if (type.type_kind == __class)
                {
                    p = is_member_data(node->left->right->type.str, &type.class_info);
                    my_var = type.class_info.variables[p];
                }
                if (node->parent_thread->parent_class != NULL)
                    my_var.is_property = 0;
                //Write mod
                if ((node->type.TT == '=') && ((node->left->type.TT == '.') || (node->left->type.TT == DYN_CALL)) && (my_var.is_property) && (my_var.writes != NULL))
                {
                    printf("awesome\n");
                    if (node->left->type.TT == DYN_CALL)
                        fprintf(out, "%s (", my_var.writes->gen_name);
                    else
                        fprintf(out, "%s (&", my_var.writes->gen_name);
                    outputnode(node->left->left, 0);
                    fprintf(out, ",");
                    outputnode(node->right, 0);
                    fprintf(out, ")");
                }
                else
                {
                    outputnode(node->left,  0);
                    fprintf(out, " %s ", get_token_str(node->type));
                    outputnode(node->right,  0);
                }
            }
        }
        fprintf(out, ")");
    }
    else
        fprintf(out, " %s ", get_token_str(node->type));

    if (EOS == 1)
        fprintf(out, ";\n", get_token_str(node->type));
}