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; }
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); }
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; }
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; } }
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; }
/* 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)); }