struct filter *convert_specifier(struct specifier_s *r, struct filtergen_opts *o) { struct filter *res = NULL; eprint("converting specifier\n"); if (r->compound) { eprint("converting compound specifier\n"); res = convert_compound_specifier(r->compound, o); } else if (r->direction) { res = convert_direction(r->direction, o); } else if (r->target) { enum filtertype type; eprint("converting target specifier\n"); switch (r->target->type) { case TOK_ACCEPT: type = T_ACCEPT; break; case TOK_REJECT: type = T_REJECT; break; case TOK_DROP: type = DROP; break; case TOK_MASQ: type = MASQ; break; case TOK_PROXY: type = REDIRECT; break; case TOK_REDIRECT: type = REDIRECT; break; default: filter_error(r->pos, "incorrect target type encountered"); type = YYEOF; break; } res = new_filter_target(type, r->pos); } else if (r->host) { res = convert_host_specifier(r->host, o); } else if (r->protocol) { res = convert_protocol_specifier(r->protocol, o); } else if (r->port) { res = convert_port_specifier(r->port, o); } else if (r->icmptype) { res = convert_icmptype_specifier(r->icmptype, o); } else if (r->option) { res = convert_option_specifier(r->option); } else if (r->chaingroup) { res = convert_chaingroup_specifier(r->chaingroup, o); } else { filter_error(r->pos, "no specifiers"); } if (res) res->pos = r->pos; free(r); return res; }
static void generate_result_dispatcher_method(const method_type* method, ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index) { arg_type* arg; Method* dispatchMethod; Variable* dispatchParam; resultsDispatcherClass->AddMethod(index, method->name.data, &dispatchMethod, &dispatchParam); Variable* classLoader = NULL; Variable* resultData = new Variable(RPC_DATA_TYPE, "resultData"); dispatchMethod->statements->Add(new VariableDeclaration(resultData, new NewExpression(RPC_DATA_TYPE, 1, dispatchParam))); // The callback method itself MethodCall* realCall = new MethodCall( new Cast(resultsInterfaceType, new FieldVariable(THIS_VALUE, "callback")), results_method_name(method->name.data)); // The return value { Type* t = NAMES.Search(method->type.type.data); if (t != VOID_TYPE) { Variable* rv = new Variable(t, "rv"); dispatchMethod->statements->Add(new VariableDeclaration(rv)); generate_create_from_data(t, dispatchMethod->statements, "_result", rv, resultData, &classLoader); realCall->arguments.push_back(rv); } } VariableFactory stubArgs("arg"); arg = method->args; while (arg != NULL) { if (convert_direction(arg->direction.data) & OUT_PARAMETER) { // Unmarshall the results Type* t = NAMES.Search(arg->type.type.data); Variable* v = stubArgs.Get(t); dispatchMethod->statements->Add(new VariableDeclaration(v)); generate_create_from_data(t, dispatchMethod->statements, arg->name.data, v, resultData, &classLoader); // Add the argument to the callback realCall->arguments.push_back(v); } arg = arg->next; } // Call the callback method IfStatement* ifst = new IfStatement; ifst->expression = new Comparison(new FieldVariable(THIS_VALUE, "callback"), "!=", NULL_VALUE); dispatchMethod->statements->Add(ifst); ifst->statements->Add(realCall); }
// ================================================= static Type* generate_results_method(const method_type* method, RpcProxyClass* proxyClass) { arg_type* arg; string resultsMethodName = results_method_name(method->name.data); Type* resultsInterfaceType = new Type(results_class_name(method->name.data), Type::GENERATED, false, false, false); if (!method->oneway) { Class* resultsClass = new Class; resultsClass->modifiers = STATIC | PUBLIC; resultsClass->what = Class::INTERFACE; resultsClass->type = resultsInterfaceType; Method* resultMethod = new Method; resultMethod->comment = gather_comments(method->comments_token->extra); resultMethod->modifiers = PUBLIC; resultMethod->returnType = VOID_TYPE; resultMethod->returnTypeDimension = 0; resultMethod->name = resultsMethodName; if (0 != strcmp("void", method->type.type.data)) { resultMethod->parameters.push_back(new Variable(NAMES.Search(method->type.type.data), "_result", method->type.dimension)); } arg = method->args; while (arg != NULL) { if (convert_direction(arg->direction.data) & OUT_PARAMETER) { resultMethod->parameters.push_back(new Variable( NAMES.Search(arg->type.type.data), arg->name.data, arg->type.dimension)); } arg = arg->next; } resultsClass->elements.push_back(resultMethod); if (resultMethod->parameters.size() > 0) { proxyClass->elements.push_back(resultsClass); return resultsInterfaceType; } } //delete resultsInterfaceType; return NULL; }
static void generate_method(const method_type* method, Class* interface, StubClass* stubClass, ProxyClass* proxyClass, int index) { arg_type* arg; int i; bool hasOutParams = false; const bool oneway = proxyClass->mOneWay || method->oneway; // == the TRANSACT_ constant ============================================= string transactCodeName = "TRANSACTION_"; transactCodeName += method->name.data; //char transactCodeValue[60]; //sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index); //Field* transactCode = new Field(STATIC | FINAL, // new Variable(INT_TYPE, transactCodeName)); //transactCode->value = transactCodeValue; //interface->elements.push_back(transactCode); if (interface->methodEnum == 0) interface->methodEnum = new Enum(); EnumItem* item = new EnumItem(); item->name = transactCodeName; if (interface->methodEnum->items.size() == 0) item->value = "IBinder::FIRST_CALL_TRANSACTION"; else item->value = ""; interface->methodEnum->items.push_back(item); interface->declareMetaInterfaceName = string(interface->type->Name().c_str() + 1); interface->implementMetaInterfaceName = string(interface->type->Name().c_str() + 1); // +JDN //interface->implementMetaInterfaceDesc = interface->type->CPPQualifiedName(); interface->implementMetaInterfaceDesc = interface->type->QualifiedName(); // -JDN // == the declaration in the interface =================================== Method* decl = new Method; decl->comment = gather_comments(method->comments_token->extra); decl->modifiers = VIRTUAL; decl->returnType = NAMES.Search(method->type.type.data); decl->returnTypeDimension = method->type.dimension; decl->name = method->name.data; arg = method->args; while (arg != NULL) { Type* vType = NAMES.Search(arg->type.type.data); Variable* v = new Variable( vType, arg->name.data, arg->type.dimension); UserDataType* userDataType = dynamic_cast<UserDataType*>(vType); if (userDataType != NULL) { v->modifiers = POINTER; } decl->parameters.push_back(v); arg = arg->next; } // No exception in C++ //decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE); interface->elements.push_back(decl); // == the stub method ==================================================== Case* c = new Case(transactCodeName); Variable* thisVar = new Variable(interface->type, "this"); thisVar->modifiers = POINTER; MethodCall* realCall = new MethodCall(thisVar/*THIS_VALUE*/, method->name.data); // interface token validation is the very first thing we do string getDescriptor = interface->type->Name() + string("::getInterfaceDescriptor()"); // +JDN Don t do checkInterface + enforceInterface it broke serialization // c->statements->Add(new MethodCall(stubClass->transact_data, // "enforceInterface", 1, new LiteralExpression(getDescriptor/*"DESCRIPTOR"*/))); // -JDN // args Variable* cl = NULL; VariableFactory stubArgs("_arg"); arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = stubArgs.Get(t); UserDataType* userDataType = dynamic_cast<UserDataType*>(t); InterfaceType* interfaceType = dynamic_cast<InterfaceType*>(t); if (userDataType != NULL) v->modifiers |= POINTER; else if (interfaceType != NULL) v->modifiers |= STRONG_POINTER; //if (userDataType != NULL) v->modifiers |= CALL_POINTER; v->dimension = arg->type.dimension; c->statements->Add(new VariableDeclaration(v)); if (convert_direction(arg->direction.data) & IN_PARAMETER) { generate_create_from_parcel(t, c->statements, v, stubClass->transact_data, &cl); } else { if (arg->type.dimension == 0) { c->statements->Add(new Assignment(v, new NewExpression(v->type))); } else if (arg->type.dimension == 1) { generate_new_array(v->type, c->statements, v, stubClass->transact_data); } else { fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); } } realCall->arguments.push_back(v); arg = arg->next; } // the real call Variable* _result = NULL; if (0 == strcmp(method->type.type.data, "void")) { c->statements->Add(realCall); if (!oneway) { // report that there were no exceptions MethodCall* ex = new MethodCall(stubClass->transact_reply, "writeNoException", 0); c->statements->Add(ex); } } else { _result = new Variable(decl->returnType, "_result", decl->returnTypeDimension); UserDataType* userDataType = dynamic_cast<UserDataType*>(decl->returnType); InterfaceType* interfaceType = dynamic_cast<InterfaceType*>(decl->returnType); if (userDataType != NULL) _result->modifiers = POINTER; else if (interfaceType != NULL) _result->modifiers = STRONG_POINTER; c->statements->Add(new VariableDeclaration(_result, realCall)); if (!oneway) { // report that there were no exceptions MethodCall* ex = new MethodCall(stubClass->transact_reply, "writeNoException", 0); c->statements->Add(ex); } // marshall the return value generate_write_to_parcel(decl->returnType, c->statements, _result, stubClass->transact_reply, Type::PARCELABLE_WRITE_RETURN_VALUE); } // out parameters i = 0; arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = stubArgs.Get(i++); if (convert_direction(arg->direction.data) & OUT_PARAMETER) { generate_write_to_parcel(t, c->statements, v, stubClass->transact_reply, Type::PARCELABLE_WRITE_RETURN_VALUE); hasOutParams = true; } arg = arg->next; } // return true c->statements->Add(new ReturnStatement(new LiteralExpression("NO_ERROR"))); stubClass->transact_switch->cases.push_back(c); // == the proxy method =================================================== Method* proxy = new Method; proxy->comment = gather_comments(method->comments_token->extra); proxy->modifiers = PUBLIC | OVERRIDE; proxy->returnType = NAMES.Search(method->type.type.data); proxy->returnTypeDimension = method->type.dimension; proxy->name = method->name.data; proxy->statements = new StatementBlock; proxy->classType = proxyClass->type; arg = method->args; while (arg != NULL) { Type* vType = NAMES.Search(arg->type.type.data); Variable* v = new Variable( vType, arg->name.data, arg->type.dimension); UserDataType* userDataType = dynamic_cast<UserDataType*>(vType); InterfaceType* interfaceType = dynamic_cast<InterfaceType*>(vType); if (userDataType != NULL) { v->modifiers |= POINTER; } else if (interfaceType != NULL) { v->modifiers |= STRONG_POINTER; } proxy->parameters.push_back(v/*new Variable( NAMES.Search(arg->type.type.data), arg->name.data, arg->type.dimension)*/); arg = arg->next; } //proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE); proxyClass->elements.push_back(proxy); // the parcels Variable* _data = new Variable(PARCEL_TYPE, "_data"); //proxy->statements->Add(new VariableDeclaration(_data, // new MethodCall(PARCEL_TYPE, "obtain"))); proxy->statements->Add(new VariableDeclaration(_data)); Variable* _reply = NULL; if (!oneway) { _reply = new Variable(PARCEL_TYPE, "_reply"); //proxy->statements->Add(new VariableDeclaration(_reply, // new MethodCall(PARCEL_TYPE, "obtain"))); proxy->statements->Add(new VariableDeclaration(_reply)); } // the return value _result = NULL; if (0 != strcmp(method->type.type.data, "void")) { _result = new Variable(proxy->returnType, "_result", method->type.dimension); UserDataType* userDataType = dynamic_cast<UserDataType*>(proxy->returnType); InterfaceType* interfaceType = dynamic_cast<InterfaceType*>(proxy->returnType); if (userDataType != NULL) { _result->modifiers = POINTER; } else if (interfaceType != NULL) { _result->modifiers = STRONG_POINTER; } proxy->statements->Add(new VariableDeclaration(_result)); } // try and finally //TryStatement* tryStatement = new TryStatement(); //proxy->statements->Add(tryStatement); //FinallyStatement* finallyStatement = new FinallyStatement(); //proxy->statements->Add(finallyStatement); // the interface identifier token: the DESCRIPTOR constant, marshalled as a string /*tryStatement*/proxy->statements->Add(new MethodCall(_data, "writeInterfaceToken", 1, new LiteralExpression(getDescriptor/*"DESCRIPTOR"*/))); // the parameters arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = new Variable(t, arg->name.data, arg->type.dimension); int dir = convert_direction(arg->direction.data); v->modifiers |= POINTER; if (dir == OUT_PARAMETER && arg->type.dimension != 0) { IfStatement* checklen = new IfStatement(); checklen->expression = new Comparison(v, "==", NULL_VALUE); checklen->statements->Add(new MethodCall(_data, "writeInt", 1, new LiteralExpression("-1"))); checklen->elseif = new IfStatement(); checklen->elseif->statements->Add(new MethodCall(_data, "writeInt", 1, new FieldVariable(v, "length"))); /*tryStatement*/proxy->statements->Add(checklen); } else if (dir & IN_PARAMETER) { // +JDN // ALERT LEAK !!!! Variable* localParcel = new Variable(); localParcel->type = _data->type; localParcel->name = _data->name; localParcel->dimension = _data->dimension; localParcel->modifiers = _data->modifiers; localParcel->modifiers |= CALL_REFERENCE; // printf("generating parcel for %s (%s)\n", v->name.c_str(), v->type->Name().c_str()); //generate_write_to_parcel(t, /*tryStatement*/proxy->statements, v, _data, 0); generate_write_to_parcel(t, /*tryStatement*/proxy->statements, v, localParcel, 0); // -JDN } else { // printf("else\n", ""); // Do nothing } arg = arg->next; } // the transact call Variable* callReply = NULL; if (_reply != NULL) { callReply = new Variable(_reply->type, _reply->name); callReply->modifiers = CALL_REFERENCE; } MethodCall* call = new MethodCall(/*proxyClass->mRemote*/ new LiteralExpression("(*(remote()))"), "transact", 4, new LiteralExpression(/*"Stub." +*/ transactCodeName), _data, callReply ? callReply : NULL_VALUE, new LiteralExpression( oneway ? /*"android.os.IBinder.FLAG_ONEWAY"*/ "IBinder::FLAG_ONEWAY" : "0")); /*tryStatement*/proxy->statements->Add(call); // throw back exceptions. if (_reply) { MethodCall* ex = new MethodCall(_reply, "readExceptionCode", 0); /*tryStatement*/proxy->statements->Add(ex); } // returning and cleanup if (_reply != NULL) { if (_result != NULL) { generate_create_from_parcel(proxy->returnType, /*tryStatement*/proxy->statements, _result, _reply, &cl); } // the out/inout parameters arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = new Variable(t, arg->name.data, arg->type.dimension); UserDataType* userDataType = dynamic_cast<UserDataType*>(t); if (userDataType != NULL) v->modifiers = POINTER; if (convert_direction(arg->direction.data) & OUT_PARAMETER) { generate_read_from_parcel(t, /*tryStatement*/proxy->statements, v, _reply, &cl); } arg = arg->next; } //finallyStatement->statements->Add(new MethodCall(_reply, "recycle")); } //finallyStatement->statements->Add(new MethodCall(_data, "recycle")); if (_result != NULL) { proxy->statements->Add(new ReturnStatement(_result)); } }
static void generate_proxy_method(const method_type* method, RpcProxyClass* proxyClass, ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index) { arg_type* arg; Method* proxyMethod = new Method; proxyMethod->comment = gather_comments(method->comments_token->extra); proxyMethod->modifiers = PUBLIC; proxyMethod->returnType = VOID_TYPE; proxyMethod->returnTypeDimension = 0; proxyMethod->name = method->name.data; proxyMethod->statements = new StatementBlock; proxyClass->elements.push_back(proxyMethod); // The local variables Variable* _data = new Variable(RPC_DATA_TYPE, "_data"); proxyMethod->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE))); // Add the arguments arg = method->args; while (arg != NULL) { if (convert_direction(arg->direction.data) & IN_PARAMETER) { // Function signature Type* t = NAMES.Search(arg->type.type.data); Variable* v = new Variable(t, arg->name.data, arg->type.dimension); proxyMethod->parameters.push_back(v); // Input parameter marshalling generate_write_to_data(t, proxyMethod->statements, new StringLiteralExpression(arg->name.data), v, _data); } arg = arg->next; } // If there is a results interface for this class Expression* resultParameter; if (resultsInterfaceType != NULL) { // Result interface parameter Variable* resultListener = new Variable(resultsInterfaceType, "_result"); proxyMethod->parameters.push_back(resultListener); // Add the results dispatcher callback resultsDispatcherClass->needed = true; resultParameter = new NewExpression(resultsDispatcherClass->type, 2, new LiteralExpression(format_int(index)), resultListener); } else { resultParameter = NULL_VALUE; } // All proxy methods take an error parameter Variable* errorListener = new Variable(RPC_ERROR_LISTENER_TYPE, "_errors"); proxyMethod->parameters.push_back(errorListener); // Call the broker proxyMethod->statements->Add(new MethodCall(new FieldVariable(THIS_VALUE, "_broker"), "sendRpc", 5, proxyClass->endpoint, new StringLiteralExpression(method->name.data), new MethodCall(_data, "serialize"), resultParameter, errorListener)); }
void DispatcherClass::AddMethod(const method_type* method) { arg_type* arg; // The if/switch statement IfStatement* ifs = new IfStatement(); ifs->expression = new MethodCall(new StringLiteralExpression(method->name.data), "equals", 1, this->actionParam); StatementBlock* block = ifs->statements = new StatementBlock; if (this->dispatchIfStatement == NULL) { this->dispatchIfStatement = ifs; this->processMethod->statements->Add(dispatchIfStatement); } else { this->dispatchIfStatement->elseif = ifs; this->dispatchIfStatement = ifs; } // The call to decl (from above) MethodCall* realCall = new MethodCall(this->targetExpression, method->name.data); // args Variable* classLoader = NULL; VariableFactory stubArgs("_arg"); arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = stubArgs.Get(t); v->dimension = arg->type.dimension; // Unmarshall the parameter block->Add(new VariableDeclaration(v)); if (convert_direction(arg->direction.data) & IN_PARAMETER) { generate_create_from_data(t, block, arg->name.data, v, this->requestData, &classLoader); } else { if (arg->type.dimension == 0) { block->Add(new Assignment(v, new NewExpression(v->type))); } else if (arg->type.dimension == 1) { generate_new_array(v->type, block, v, this->requestData); } else { fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); } } // Add that parameter to the method call realCall->arguments.push_back(v); arg = arg->next; } // Add a final parameter: RpcContext. Contains data about // incoming request (e.g., certificate) realCall->arguments.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0)); Type* returnType = NAMES.Search(method->type.type.data); if (returnType == EVENT_FAKE_TYPE) { returnType = VOID_TYPE; } // the real call bool first = true; Variable* _result = NULL; if (returnType == VOID_TYPE) { block->Add(realCall); } else { _result = new Variable(returnType, "_result", method->type.dimension); block->Add(new VariableDeclaration(_result, realCall)); // need the result RpcData if (first) { block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE))); first = false; } // marshall the return value generate_write_to_data(returnType, block, new StringLiteralExpression("_result"), _result, this->resultData); } // out parameters int i = 0; arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = stubArgs.Get(i++); if (convert_direction(arg->direction.data) & OUT_PARAMETER) { // need the result RpcData if (first) { block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE))); first = false; } generate_write_to_data(t, block, new StringLiteralExpression(arg->name.data), v, this->resultData); } arg = arg->next; } }
static void generate_method(const method_type* method, Class* interface, StubClass* stubClass, ProxyClass* proxyClass, int index) { arg_type* arg; int i; bool hasOutParams = false; const bool oneway = proxyClass->mOneWay || method->oneway; // == the TRANSACT_ constant ============================================= string transactCodeName = "TRANSACTION_"; transactCodeName += method->name.data; char transactCodeValue[50]; sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index); Field* transactCode = new Field(STATIC | FINAL, new Variable(INT_TYPE, transactCodeName)); transactCode->value = transactCodeValue; stubClass->elements.push_back(transactCode); // == the declaration in the interface =================================== Method* decl = new Method; decl->comment = gather_comments(method->comments_token->extra); decl->modifiers = PUBLIC; decl->returnType = NAMES.Search(method->type.type.data); decl->returnTypeDimension = method->type.dimension; decl->name = method->name.data; arg = method->args; while (arg != NULL) { decl->parameters.push_back(new Variable( NAMES.Search(arg->type.type.data), arg->name.data, arg->type.dimension)); arg = arg->next; } decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE); interface->elements.push_back(decl); // == the stub method ==================================================== Case* c = new Case(transactCodeName); MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data); // interface token validation is the very first thing we do c->statements->Add(new MethodCall(stubClass->transact_data, "enforceInterface", 1, new LiteralExpression("DESCRIPTOR"))); // args Variable* cl = NULL; VariableFactory stubArgs("_arg"); arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = stubArgs.Get(t); v->dimension = arg->type.dimension; c->statements->Add(new VariableDeclaration(v)); if (convert_direction(arg->direction.data) & IN_PARAMETER) { generate_create_from_parcel(t, c->statements, v, stubClass->transact_data, &cl); } else { if (arg->type.dimension == 0) { c->statements->Add(new Assignment( v, new NewExpression(v->type))); } else if (arg->type.dimension == 1) { generate_new_array(v->type, c->statements, v, stubClass->transact_data); } else { fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); } } realCall->arguments.push_back(v); arg = arg->next; } // the real call Variable* _result = NULL; if (0 == strcmp(method->type.type.data, "void")) { c->statements->Add(realCall); if (!oneway) { // report that there were no exceptions MethodCall* ex = new MethodCall(stubClass->transact_reply, "writeNoException", 0); c->statements->Add(ex); } } else { _result = new Variable(decl->returnType, "_result", decl->returnTypeDimension); c->statements->Add(new VariableDeclaration(_result, realCall)); if (!oneway) { // report that there were no exceptions MethodCall* ex = new MethodCall(stubClass->transact_reply, "writeNoException", 0); c->statements->Add(ex); } // marshall the return value generate_write_to_parcel(decl->returnType, c->statements, _result, stubClass->transact_reply, Type::PARCELABLE_WRITE_RETURN_VALUE); } // out parameters i = 0; arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = stubArgs.Get(i++); if (convert_direction(arg->direction.data) & OUT_PARAMETER) { generate_write_to_parcel(t, c->statements, v, stubClass->transact_reply, Type::PARCELABLE_WRITE_RETURN_VALUE); hasOutParams = true; } arg = arg->next; } // return true c->statements->Add(new ReturnStatement(TRUE_VALUE)); stubClass->transact_switch->cases.push_back(c); // == the proxy method =================================================== Method* proxy = new Method; proxy->comment = gather_comments(method->comments_token->extra); proxy->modifiers = PUBLIC; proxy->returnType = NAMES.Search(method->type.type.data); proxy->returnTypeDimension = method->type.dimension; proxy->name = method->name.data; proxy->statements = new StatementBlock; arg = method->args; while (arg != NULL) { proxy->parameters.push_back(new Variable( NAMES.Search(arg->type.type.data), arg->name.data, arg->type.dimension)); arg = arg->next; } proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE); proxyClass->elements.push_back(proxy); // the parcels Variable* _data = new Variable(PARCEL_TYPE, "_data"); proxy->statements->Add(new VariableDeclaration(_data, new MethodCall(PARCEL_TYPE, "obtain"))); Variable* _reply = NULL; if (!oneway) { _reply = new Variable(PARCEL_TYPE, "_reply"); proxy->statements->Add(new VariableDeclaration(_reply, new MethodCall(PARCEL_TYPE, "obtain"))); } // the return value _result = NULL; if (0 != strcmp(method->type.type.data, "void")) { _result = new Variable(proxy->returnType, "_result", method->type.dimension); proxy->statements->Add(new VariableDeclaration(_result)); } // try and finally TryStatement* tryStatement = new TryStatement(); proxy->statements->Add(tryStatement); FinallyStatement* finallyStatement = new FinallyStatement(); proxy->statements->Add(finallyStatement); // the interface identifier token: the DESCRIPTOR constant, marshalled as a string tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken", 1, new LiteralExpression("DESCRIPTOR"))); // the parameters arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = new Variable(t, arg->name.data, arg->type.dimension); int dir = convert_direction(arg->direction.data); if (dir == OUT_PARAMETER && arg->type.dimension != 0) { IfStatement* checklen = new IfStatement(); checklen->expression = new Comparison(v, "==", NULL_VALUE); checklen->statements->Add(new MethodCall(_data, "writeInt", 1, new LiteralExpression("-1"))); checklen->elseif = new IfStatement(); checklen->elseif->statements->Add(new MethodCall(_data, "writeInt", 1, new FieldVariable(v, "length"))); tryStatement->statements->Add(checklen); } else if (dir & IN_PARAMETER) { generate_write_to_parcel(t, tryStatement->statements, v, _data, 0); } arg = arg->next; } // the transact call MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4, new LiteralExpression("Stub." + transactCodeName), _data, _reply ? _reply : NULL_VALUE, new LiteralExpression( oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")); tryStatement->statements->Add(call); // throw back exceptions. if (_reply) { MethodCall* ex = new MethodCall(_reply, "readException", 0); tryStatement->statements->Add(ex); } // returning and cleanup if (_reply != NULL) { if (_result != NULL) { generate_create_from_parcel(proxy->returnType, tryStatement->statements, _result, _reply, &cl); } // the out/inout parameters arg = method->args; while (arg != NULL) { Type* t = NAMES.Search(arg->type.type.data); Variable* v = new Variable(t, arg->name.data, arg->type.dimension); if (convert_direction(arg->direction.data) & OUT_PARAMETER) { generate_read_from_parcel(t, tryStatement->statements, v, _reply, &cl); } arg = arg->next; } finallyStatement->statements->Add(new MethodCall(_reply, "recycle")); } finallyStatement->statements->Add(new MethodCall(_data, "recycle")); if (_result != NULL) { proxy->statements->Add(new ReturnStatement(_result)); } }
void send() { wildfire_packet_t * wp; net_packet_t * np; uint16_t sample; uint8_t sends; sends = 0; init_devs(); mos_thread_set_suspend_state(SUSPEND_STATE_SLEEP); //sets power save mode //just wait while in init state while (state != GO) { mos_mdelay(500); } while (1) { if (state == SLEEPNODE) { disable_wind_speed(); //must disable the ext interrupts for power save sleep //mos_thread_set_suspend_state(SUSPEND_STATE_SLEEP); //sets power save mode mos_thread_sleep(SLEEP_INTERVAL - 1000); //extra 1000 to make sure it wakes up early //mos_thread_set_suspend_state(SUSPEND_STATE_IDLE); //idle mode while (state != GO) //awake, but not ready yet.. so just wait mos_mdelay(250); sends = 0; } //first populate the buffer with the net packet since this will //always be the header np = (net_packet_t *)&(sendBuf.data[0]); np->type = DATA; np->src = myID; np->dest = baseID; np->next_hop = myParentID; np->last_hop = myID; np->seqno = mySeqNo; np->pkt_dtb = myDTB; np->sender_dtb = myDTB; sendBuf.size = sizeof(net_packet_t); //for data packets, we now populate the buffer with the //wildfire packet information. Adding it to the end. wp = (wildfire_packet_t *)&(sendBuf.data[sendBuf.size]); //temp dev_open(DEV_MICA2_TEMP); dev_read(DEV_MICA2_TEMP, &sample, sizeof(sample)); dev_close(DEV_MICA2_TEMP); wp->temp = convert_temp(sample); //battery dev_open(DEV_MICA2_BATTERY); dev_read(DEV_MICA2_BATTERY, &sample, sizeof(sample)); dev_close(DEV_MICA2_BATTERY); wp->battery = sample; //humidity humidity_on(); mos_mdelay(200); //settling time dev_open(DEV_ADC); dev_ioctl(DEV_ADC, ADC_SET_CHANNEL, AVR_ADC_CH_2); dev_read(DEV_ADC, &sample, sizeof(sample)); dev_close(DEV_ADC); humidity_off(); wp->humidity = convert_humidity(sample, wp->battery); //wind direction wind_dir_on(); dev_open(DEV_ADC); dev_ioctl(DEV_ADC, ADC_SET_CHANNEL, AVR_ADC_CH_1); dev_read(DEV_ADC, &sample, sizeof(sample)); dev_close(DEV_ADC); wind_dir_off(); wp->wind_direction = convert_direction(sample); //wind speed wp->wind_speed = wind_speed; sendBuf.size += sizeof(wildfire_packet_t); //debug info: /* printf("type\tsrc\tdest\tnext\tlast\tseq\tpktdtb\ts_dtb\n"); printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", np->type, np->src, np->dest, np->next_hop, np->last_hop, np->seqno, np->pkt_dtb, np->sender_dtb); printf("temp\thmdty\tw_dir\tw_spd\tbat\n"); printf("%d\t%d\t%d\t%d\t%d\n", wp->temp, wp->humidity, wp->wind_direction, wp->wind_speed, wp->battery); */ if (rate == 0 || sends < rate*myDTB) { com_send(IFACE_RADIO, &sendBuf); mySeqNo++; sends++; } if (mySeqNo > 254) mySeqNo = 0; mos_mdelay(1000); } }