⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generaterpc.pl

📁 无线通信的主要编程软件,是无线通信工作人员的必备工具,关天相关教程我会在后续传上.
💻 PL
📖 第 1 页 / 共 2 页
字号:
    $greenToggle    if ( sendingResponse == TRUE ) {      dbg(DBG_USR2, "stopped processing because sending\\n");      post processCommand();      $yellowToggle      return;          }    if ( processingCommand == TRUE ) {      dbg(DBG_USR2, "stopped processing because already processing\\n");      $yellowToggle      return;    }    else {      processingCommand = TRUE;    }    /*fill in the response message headers*/    responseMsg->transactionID = msg->transactionID;    responseMsg->commandID = msg->commandID;    responseMsg->sourceAddress = TOS_LOCAL_ADDRESS;    responseMsg->errorCode = RPC_SUCCESS;    responseMsg->dataLength = 0;    if( (id < $num_rpcs) && (msg->dataLength != args_sizes[id]) ) {      responseMsg->errorCode = RPC_GARBAGE_ARGS;      dbg(DBG_USR2, "param size doesn't match\\n");    } else if( (id < $num_rpcs) && (return_sizes[id] + sizeof(RpcResponseMsg) > maxLength) ) {      responseMsg->errorCode = RPC_RESPONSE_TOO_LARGE;      dbg(DBG_USR2,"Return type is too large for the response packet");    } else switch( id ) {EOF#this is the heart of rpc: parse the args, call the func, pack the returnfor $fullName (sort keys %rpcFunctions ) {    $rpc = $rpcFunctions{$fullName};    $params = $rpc->{'params'};    $s = sprintf "%s\n      /*** $fullName ***/\n", $s;    $s = sprintf "%s  case $rpc->{'commandID'}: {\n", $s;    #get ready with a returnVal decl if necessary    if ( $rpc->{'returnType'}->{'typeName'} ne 'void') {        my $ptr = $rpc->{returnType}{typeClass} eq 'pointer' ? "*" : "";	$s .= "    $rpc->{returnType}{typeName}$ptr RPC_returnVal;\n";    }    #setup the parameters    for ( $count=0 ; $count < $rpc->{'numParams'} ; $count++)    {	$s = sprintf "%s    %s RPC_%s;\n", $s,	$params->{"param$count"}->{'type'}->{'typeName'}, $params->{"param$count"}->{'name'};    }        $s = sprintf "%s      dbg(DBG_USR2, \"handling commandId $rpc->{'commandID'}\\n\");\n",$s;    for ( $count=0 ; $count < $rpc->{"numParams"} ; $count++)    {        my $name = "RPC_" . $params->{"param$count"}{name};        my $type = $params->{"param$count"}{type}{typeName};        $s .= "    memcpy( &$name, byteSrc, sizeof($type) );\n";	$s .= "    byteSrc += sizeof($type);\n" if $count != ($rpc->{numParams}-1);    }        #store the return value appropriately    $s = sprintf "%s    ", $s;    if ( $rpc->{'returnType'}->{'typeName'} ne 'void') {	$s .= "RPC_returnVal = ";    }    #"call" commands or "signal" events    if ($rpc->{'functionType'} eq "command"){	$s = sprintf "%scall", $s;    }    elsif ($rpc->{'functionType'} eq "event"){	$s = sprintf "%ssignal", $s;    }    #actually invoke the function with arguments    $s = sprintf "%s $rpc->{'componentName'}_",$s;    if ( $rpc->{'interfaceName'} ){	$s = sprintf "%s$rpc->{'interfaceName'}.", $s;    }    $s = sprintf "%s$rpc->{'functionName'}( ", $s;    for ( $count=0; $count < $rpc->{'numParams'} ; $count++)    {	my $str = "RPC_".$params->{"param$count"}->{'name'};	$str = "&$str" if $params->{"param$count"}{type}{typeClass} eq "pointer";	$s .= " $str,";    }    $s = sprintf "%s\b );\n", $s;    #store the return value, if necessary    if ( $rpc->{returnType}{typeName} ne 'void') {      my $rvArg = ($rpc->{returnType}{typeClass} eq 'pointer' ? "" : "&") . "RPC_returnVal";      $s .= "    memcpy( &responseMsg->data[0], $rvArg, sizeof($rpc->{returnType}{typeName}) );\n";    }    $s = sprintf "%s      dbg(DBG_USR2, \"done calling the functions\\n\");\n",$s;    #mark the size of the return value    if ( $rpc->{'returnType'}->{'typeName'} ne 'void' ){	$s = sprintf "%s    responseMsg->dataLength = sizeof ( %s );      dbg(DBG_USR2, \"responseMsg->dataLength = %s\\n\", responseMsg->dataLength);      dbg(DBG_USR2, \" sizeof ( %s )= %s\\n\", sizeof ( %s ));  } break;", $s, $rpc->{'returnType'}->{'typeName'}, $d,    $rpc->{'returnType'}->{'typeName'}, $d,    $rpc->{'returnType'}->{'typeName'};    }    else {	$s = sprintf "%s      dbg(DBG_USR2, \"not packing void return value\\n\");  } break;", $s;    }}#phew!$s = sprintf "%s    default:        dbg(DBG_USR2, \"found no rpc function\\n\");      responseMsg->errorCode = RPC_PROCEDURE_UNAVAIL;    }    /*** now send the response message off if necessary ***/    dbg(DBG_USR2, \"errorCode=%s,dataLength=%s\\n\",responseMsg->errorCode, responseMsg->dataLength);    dbg(DBG_USR2, \"sizeof( RpcResponseMsg ) = %s, data-transactionID= %s\\n\",sizeof (RpcResponseMsg),((uint32_t)&(responseMsg->data[0]) - (uint32_t)&(responseMsg->transactionID))); /*   if (responseMsg->errorCode == RPC_SUCCESS && responseMsg->dataLength==0){      dbg(DBG_USR2, \"done processing, no return args\\n\");      processingCommand=FALSE;    }    else if (responseMsg->errorCode == RPC_SUCCESS){      //calculate the size to be the size of the data I just added       //plus the size of the responseMsg less the data array (the data array       //can sometimes take space due to compiler packing)      if (call ResponseSendMsgDrain.send(msg->returnAddress,				    responseMsg->dataLength + ( (uint32_t)&(responseMsg->data[0]) - (uint32_t)&(responseMsg->transactionID)),				    responseMsgPtr) ){        dbg(DBG_USR2, \"sending response\\n\");        sendingResponse=TRUE;      }      else{        dbg(DBG_USR2, \"sending response failed\\n\");        processingCommand=FALSE;      }    }    else{*/      if (msg->responseDesired == 0){        dbg(DBG_USR2, \"no response desired; not sending response message\");        processingCommand=FALSE;      }      else if (call ResponseSendMsgDrain.send(msg->returnAddress,				    responseMsg->dataLength + sizeof(RpcResponseMsg),				    responseMsgPtr) ){        dbg(DBG_USR2, \"sending response\\n\");        sendingResponse=TRUE;        $redToggle      }      else{        dbg(DBG_USR2, \"sending response failed\\n\");        processingCommand=FALSE;        $yellowToggle      }//    }    dbg(DBG_USR2, \"done processing.\\n\");  }  event TOS_MsgPtr CommandReceiveDrip.receive(TOS_MsgPtr pMsg, void* payload, uint16_t payloadLength) {    RpcCommandMsg* msg = (RpcCommandMsg*)payload;    dbg(DBG_USR2, \"received drip command message\\n\");    //store the drip message for later drip rebroadcasting    memcpy(dripStore.data, payload, payloadLength);    dripStoreLength = payloadLength;    //if it is destined to us, post a task to process it    if (msg->address == TOS_LOCAL_ADDRESS || msg->address == TOS_BCAST_ADDR ) {      //store another copy for later processing      memcpy(cmdStore.data, payload, payloadLength);      cmdStoreLength = payloadLength;      if (post processCommand() == SUCCESS){        dbg(DBG_USR2, \"posted task\\n\");      }       else{        dbg(DBG_USR2, \"failed to post task\\n\");      }    }    else {      dbg(DBG_USR2, \"not posting task because not for me\\n\");    }    return pMsg;  }  event TOS_MsgPtr CommandReceiveLocal.receive(TOS_MsgPtr pMsg) {    //store the drip message for later processing    dbg(DBG_USR2, \"received local command message, len=%s\\n\",pMsg->length);    memcpy(cmdStore.data, pMsg->data, pMsg->length);    cmdStoreLength = pMsg->length;    if (post processCommand() == SUCCESS){      dbg(DBG_USR2, \"posted task\\n\");    }     else{      dbg(DBG_USR2, \"failed to post task\\n\");    }    return pMsg;  }  event result_t CommandDrip.rebroadcastRequest(TOS_MsgPtr msg, void *payload) {    dbg(DBG_USR2, \"drip rebroadcast request\\n\");    memcpy(payload, dripStore.data, dripStoreLength);    call CommandDrip.rebroadcast(msg, payload, dripStoreLength);        return SUCCESS;  }  event result_t DrainSend.sendDone(TOS_MsgPtr pMsg, result_t success) {    dbg(DBG_USR2, \"wtf!!  drainSend send done\\n\");    return SUCCESS;  }  event result_t ResponseSendMsgDrain.sendDone(TOS_MsgPtr pMsg, result_t success) {    if (success == SUCCESS) {      dbg(DBG_USR2, \"drain send done: SUCCESS\\n\");    }    else{      dbg(DBG_USR2, \"drain send done: FAIL\\n\");    }    processingCommand = FALSE;    sendingResponse = FALSE;    return SUCCESS;  }/*  event result_t ErrorSendMsgDrain.sendDone(TOS_MsgPtr pMsg, result_t success) {    if (success == SUCCESS) {      dbg(DBG_USR2, \"drain error send done: SUCCESS\\n\");    }    else{      dbg(DBG_USR2, \"drain error send done: FAIL\\n\");    }    processingCommand = FALSE;    sendingResponse = FALSE;    return SUCCESS;  }*/", $s, $d, $d, $d, $d, $d;#now, print out all the provided events or uses commands that are requiredfor my $requiredFunc (values %requiredFunctions) {    $s .= sprintf("  %s %s %s.%s( ", $requiredFunc->{functionType},		  $requiredFunc->{returnType}->{typeDecl},		  $requiredFunc->{componentName}."_".$requiredFunc->{interfaceName},		  $requiredFunc->{functionName});    for my $param (values %{$requiredFunc->{params}}) {	$s .= " $param->{type}->{typeDecl} $param->{name},";    }    $s .= "\b) { }\n";}$s .= "\n}";#send the generated code out to a filemy $backsp = sprintf "\b";$s =~ s/.$backsp//g;open(RPCM, ">${DestDir}RpcM.nc");print RPCM "$G_warning$s";close(RPCM);############################### Generate the RpcC.nc file##############################$s = "includes Rpc;configuration RpcC {  provides {    interface StdControl;  }}implementation {  components     RpcM,    GenericComm,    DrainC,    DestC,    DripC,     $LedsC    DripStateC;";# generate the declarations of each rpc interface or function:my %components;for $fullName (sort keys %rpcFunctions ) {    $rpc = $rpcFunctions{$fullName};    if (! $components{$rpc->{'componentName'}}){	$components{$rpc->{'componentName'}} = 1;	$s = sprintf "%s\n    components $rpc->{'componentName'};", $s;    }}my %componentInterfaces;for $fullName (sort keys %rpcFunctions ) {    my $rpc = $rpcFunctions{$fullName};    if ( $rpc->{'interfaceName'} ){	if (! $componentInterfaces{$rpc->{'componentName'}.$rpc->{'interfaceName'}}){	    $componentInterfaces{$rpc->{'componentName'}.$rpc->{'interfaceName'}} = 1;	    $s = sprintf "%s\n    RpcM.$rpc->{'componentName'}_$rpc->{'interfaceName'}", $s;	    if ($rpc->{'provided'}==1){		$s = sprintf "%s -> ", $s;	    }	    else{		$s = sprintf "%s <- ", $s;	    }	    $s = sprintf "%s$rpc->{'componentName'}.$rpc->{'interfaceName'};", $s;	}    }    else{	$s = sprintf "%s\n    RpcM.$rpc->{'componentName'}_$rpc->{'functionName'}", $s;	if ($rpc->{'provided'}==1){	    $s = sprintf "%s -> ", $s;	}	else{	    $s = sprintf "%s <- ", $s;	}	$s = sprintf "%s$rpc->{'componentName'}.$rpc->{'functionName'};", $s;    }}$s = sprintf "%s  //now do all the wiring for the rpc communication:  StdControl = RpcM;  $ledsWiring    RpcM.SubControl -> GenericComm;  RpcM.SubControl -> DrainC;  RpcM.SubControl -> DripC;  //genericComm wiring  RpcM.CommandReceiveLocal -> GenericComm.ReceiveMsg[AM_RPCCOMMANDMSG];  //drip wiring  RpcM.CommandReceiveDrip -> DripC.Receive[AM_RPCCOMMANDMSG];  RpcM.CommandDrip -> DripC.Drip[AM_RPCCOMMANDMSG];  DripC.DripState[AM_RPCCOMMANDMSG] -> DripStateC.DripState[unique(\"DripState\")];  RpcM.Dest -> DestC;  //drain wiring  RpcM.ResponseSendMsgDrain -> DrainC.SendMsg[AM_RPCRESPONSEMSG];//  RpcM.ErrorSendMsgDrain -> DrainC.SendMsg[AM_RPCERRORMSG];  RpcM.DrainSend -> DrainC.Send[AM_RPCRESPONSEMSG];}", $s;#send the generated code out to a file$s =~ s/.$backsp//g;open(RPCC, ">${DestDir}RpcC.nc");print RPCC "$G_warning$s";close(RPCC);############################# Substitute abstract params# This function is only here to pass a hashref by value############################sub substituteAbstractParams{    my ($params, $typeNames, $typeVals) = @_;    my %newParams = ();    my $i = 0;    for my $name (keys %{$params}) {	my $param = $params->{$name};	my %newParam = ();	$newParam{'name'} = $param->{'name'};	$newParam{'type'} = &substituteAbstractTypes($param->{'type'},						     $typeNames,						     $typeVals);	$newParams{$name} = \%newParam;	$i++;    }    return \%newParams;}    ############################# Match a type with an abstract type definition and, if it matches# substitute the type parameter used when the interface was declared############################sub substituteAbstractTypes{    my ($type, $typeNames, $typeVals) = @_;    my $i = 0;    for my $typeName (@{$typeNames}) {	if ( $type->{typeName} eq $typeName ) {	    return &NescParser::parseType($typeVals->[$i]);	}	$i++;    }    return $type}############################## check the following criteria of any rpc function:# 1.  any provided rpc interface has only commands# 2.  any used rpc interface has only events# 3.  all rpc commands and events are provided# 4.  no rpc function has void* param or return types# 5.  no rpc function defined in generic modules##############################sub checkRpcFunction {    my ($rpc, $fullName) = @_;    #if this is an interface function, provided/used depends on command/event    if ( $rpc->{'interfaceName'}){	if ($rpc->{'provided'}==1 &&	    $rpc->{'functionType'} eq 'event'){	    print "WARNING: rpc function $fullName is an event in a provided interface; it is now being handled by RpcM.\n";	    return 1;	}	elsif ( $rpc->{'provided'}==0 &&		$rpc->{'functionType'} eq 'command'){	    print "WARNING: rpc function $fullName is a command in a used interface; it is now being handled by RpcM.\n";	    return 1;	}    }    #if this is a function not in an interface, it must be provided    else{	if ($rpc->{'provided'}==0 ){	    print "ERROR: rpc function $fullName is used; it cannot be tagged \@rpc.\n";	    $shouldDie = 1;	}    }    if ( $rpc->{'returnType'}->{'typeName'} eq 'void' &&	 $rpc->{'returnType'}->{'typeClass'} eq 'pointer'){	print "ERROR: rpc function $fullName returns a void*.\n";	$shouldDie = 1;    }    for my $param (values %{$rpc->{'params'}}){	if ($param->{'type'}->{'typeName'} eq 'void' &&	    $param->{'type'}->{'typeClass'} eq 'pointer'){	    print "ERROR: rpc function $fullName has a void* parameter.\n";	    $shouldDie = 1;	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -