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

📄 generaterpc.pl

📁 无线通信的主要编程软件,是无线通信工作人员的必备工具,关天相关教程我会在后续传上.
💻 PL
📖 第 1 页 / 共 2 页
字号:
#!/usr/bin/perl -w# "Copyright (c) 2000-2003 The Regents of the University of California.  # All rights reserved.## Permission to use, copy, modify, and distribute this software and its# documentation for any purpose, without fee, and without written agreement# is hereby granted, provided that the above copyright notice, the following# two paragraphs and the author appear in all copies of this software.# # IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT# OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY# OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# # THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY# AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS# ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."## @author Kamin Whitehouse #use XML::Simple;use strict;use FindBin;use lib $FindBin::Bin;use AtTags;use NescParser;my $DestDir = "";my $useLeds = 0;#get rid of extraneous argumentsmy @args = @ARGV;@ARGV = ();while (@args){    my $arg = shift @args;    if ($arg eq "-DRPC_LEDS"){	$useLeds = 1;    }    elsif ($arg eq "-d") {        $DestDir = shift @args;        $DestDir .= "/" unless $arg =~ m{/$};     } elsif ($arg !~ m/^-[^I]/) {	push @ARGV, $arg;    }}#}#add a few more directories that should always be on the search pathunshift ( @ARGV, "-I".$ENV{'TOSDIR'}."/types/" );unshift ( @ARGV, "-I".$ENV{'TOSDIR'}."/interfaces/" );unshift ( @ARGV, "-I".$ENV{'TOSDIR'}."/system/" );unshift ( @ARGV, "-I".$ENV{'PWD'}."/" );#make sure the user knows what's going on:my $s = "generateRpc.pl ";for my $arg (@ARGV) {    $s = sprintf "%s %s", $s, $arg;}print $s, "\n";my $nescXml = pop(@ARGV);############################### look through the @rpc tags to find all unique rpc instances##############################my ($taggedInterfaces, $includes) = AtTags::getTaggedInterfaces(@ARGV, "rpc", ());my ($taggedFunctions, $includesB) = AtTags::getTaggedFunctions(@ARGV, "rpc", ());for my $include (keys %$includesB){    $includes->{$include} = 1;}############################### look through the code and get definitions of all interfaces##############################my $interfaces = NescParser::getInterfaces($nescXml);############################### load the struct definitions ###############################my $structs = NescParser::getStructs($nescXml);#print "there are %d structs\n\n",scalar keys %$structs;############################### go through all tagged interfaces and functions and come up with# complete list of rpc functions## The desired structure is the following, and will be used to create# rpc.schema ## %rpcFunctions--->fullName--->commandNumber#                           |->componentName#                           |->interfaceName#                           |->functionName#                           |->provided#                           |->functionType#                           |->returnType#                           |->%params## where "fullName" is either moduleM.interface.func or moduleM.func.## while creating this structure, we also check the validity criteria below:##############################my %rpcFunctions;my %requiredFunctions;my $fullName;my $shouldDie=0;# add each tagged functionfor my $taggedFunction (@$taggedFunctions){    $fullName = $taggedFunction->{'componentName'}.".".$taggedFunction->{'functionName'};    checkRpcFunction($taggedFunction, $fullName);    $rpcFunctions{$fullName} = $taggedFunction;}# add each function in each tagged interfacefor my $taggedInterface (@$taggedInterfaces){    my $interface;    my $functions;    if ($interfaces->{$taggedInterface->{'interfaceType'}}){	$interface = $interfaces->{$taggedInterface->{'interfaceType'}};	$functions = $interface->{'functions'};    }    else{	print "WARNING: rpc interface $taggedInterface->{'interfaceType'} not found.";    }    while (my ($functionName, $function) = each (%$functions) ){	my %rpc;	$rpc{'componentName'} = $taggedInterface->{'componentName'};	$rpc{'interfaceType'} = $taggedInterface->{'interfaceType'};	$rpc{'interfaceName'} = $taggedInterface->{'interfaceName'};	$rpc{'functionName'} = $functionName;	$rpc{'provided'} = $taggedInterface->{'provided'};	$rpc{'functionType'} = $function->{'functionType'};	$rpc{'returnType'} = $function->{'returnType'};	$rpc{'params'} = $function->{'params'};	if ($interface->{'abstract'}==1){	    $rpc{'gparams'} = $taggedInterface->{'gparams'};	    $rpc{'returnType'} = &substituteAbstractTypes($rpc{'returnType'},							  $interface->{'gparams'}, 							  $taggedInterface->{'gparams'});	    $rpc{'params'} = &substituteAbstractParams($rpc{'params'},						       $interface->{'gparams'}, 						       $taggedInterface->{'gparams'});	}	$rpc{'numParams'} = $function->{'numParams'};	$fullName = $rpc{'componentName'}.".".$rpc{'interfaceName'}.".".$rpc{'functionName'};	if (checkRpcFunction(\%rpc, $fullName)){	    $requiredFunctions{$fullName} = \%rpc;	}	else{	    $rpcFunctions{$fullName} = \%rpc;	}    }}    #The following variable is set in the checkRpcFunction subroutine.#We wait until after all functions are checked before dieing so that#we can get all error messages at onceif ($shouldDie == 1) { die "Too many errors.";}    ############################### Number the rpc functions alphabetically##############################my $count = 0;my $rpc;for $fullName (sort keys %rpcFunctions ) {    $rpc = $rpcFunctions{$fullName};    $rpc->{'commandID'} = $count++;}############################### print out the parsed info for debugging/user knowledge.# Simultaneously, generate each rpc function signature.##############################my $params;my $bspace = sprintf "\b";if (keys %rpcFunctions){    $s = "Adding rpc functions:\n";     for $fullName (sort keys %rpcFunctions ) {	$rpc = $rpcFunctions{$fullName};	my $signature = sprintf "%25s %s ( ", "$rpc->{'functionType'} $rpc->{'returnType'}->{'typeDecl'}", $fullName;	my $sigLength = length($signature);	$params = $rpc->{'params'};	for ($count=0; $count < $rpc->{'numParams'} ; $count++,)	{	    if ($count>0){		$signature .= sprintf "\n%${sigLength}s%s,","",		$params->{"param$count"}->{'type'}->{'typeDecl'}." ".$params->{"param$count"}->{'name'}; 	    }	    else{		$signature .= sprintf "%s %s,",		$params->{"param$count"}->{'type'}->{'typeDecl'},		$params->{"param$count"}->{'name'};	    }	}	$signature .= sprintf "\b )\n";		$s .= $signature;	$signature =~ s/\s+/ /g;	$signature =~ s/.$bspace/ /g;	$rpc->{'signature'} = $signature;    }    print "$s\n"; }else{    print "** Warning: no RPC functions found.\n\n"; }	############################### print out in XML format for the PC-side tools##############################my $xs1 = XML::Simple->new();my %xmlOutHash = ();$xmlOutHash{'rpcFunctions'} = \%rpcFunctions;my %tmpHash = ();#$tmpHash{'struct'} = $structs;#$xmlOutHash{'structs'} = \%tmpHash;my $str = $xs1->XMLout(\%xmlOutHash, RootName=>"rpcSchema", KeyAttr=>{'attribute'=>'name', 'event'=>'name', 'symbol'=>'name'}, XMLDecl=>1);SlurpFile::dump_file( "${DestDir}rpcSchema.xml", "$str" );############################### Create a warning at the top of each generated file##############################my $G_warning =<< 'EOF';// *** WARNING ****** WARNING ****** WARNING ****** WARNING ****** WARNING ***// ***                                                                     ***// *** This file was automatically generated by generateRpc.pl.   ***// *** Any and all changes made to this file WILL BE LOST!                 ***// ***                                                                     ***// *** WARNING ****** WARNING ****** WARNING ****** WARNING ****** WARNING ***EOFmy $yellowToggle = "";my $greenToggle = "";my $redToggle = "";my $Leds = "";my $LedsC = "";my $ledsWiring = "";if ($useLeds) {    $yellowToggle = "call Leds.yellowToggle();";    $greenToggle = "call Leds.greenToggle();";    $redToggle = "call Leds.redToggle();";    $Leds = "interface Leds;";    $LedsC = "LedsC,";    $ledsWiring = "RpcM.Leds -> LedsC;"}############################### Generate the RpcM.nc file##############################$includes->{'includes Drain;'}=1;$includes->{'includes Rpc;'}=1;$s = "";for my $include (keys %$includes){    $s .= "$include\n";}$s .= "module RpcM {  provides {    interface StdControl;    /*** events that are rpc-able ***/";my $componentName="";my $interfaceName="";my $gparams = "";# generate the "provides" declarations of rpc-able eventsfor $fullName (sort keys %rpcFunctions ) {    $rpc = $rpcFunctions{$fullName};    if ($rpc->{'provided'} == 1){	next;    }    if ($rpc->{'interfaceName'}){	if ( $componentName ne $rpc->{'componentName'} ||	     $interfaceName ne $rpc->{'interfaceName'} ) {	    $componentName = $rpc->{'componentName'};	    $interfaceName = $rpc->{'interfaceName'};	    $gparams = "";	    if ($rpc->{'gparams'}){		$gparams = "<";		for my $gparam (@{$rpc->{'gparams'}}) {		    $gparams .= $gparam;		}				$gparams .= ">";	    }	    $s = sprintf "%s    interface $rpc->{'interfaceType'}$gparams as $componentName\_$interfaceName;\n", $s;	}    }    else{	print keys %$rpc;	$params = $rpc->{'params'};	$s = sprintf "%s    $rpc->{'functionType'} $rpc->{'returnType'}->{'typeDecl'} $rpc->{'componentName'}_$rpc->{'functionName'} (  ", $s;	for ($count=0; $count < $rpc->{'numParams'} ; $count++)	{	    $s = sprintf "%s %s %s,", $s, $params->{"param$count"}->{'type'}->{'typeDecl'},  $params->{"param$count"}->{'name'};	}	$s = sprintf "%s\b );\n", $s;	    }}$s = sprintf "%s  }  uses {    interface StdControl as SubControl;    $Leds    interface ReceiveMsg as CommandReceiveLocal;    interface SendMsg as ResponseSendMsgDrain;//    interface SendMsg as ErrorSendMsgDrain;    interface Send as DrainSend;    interface Receive as CommandReceiveDrip;    interface Drip as CommandDrip;    interface Dest;    /*** commands that are rpc-able ***/", $s;# generate the "uses" declarations of rpc-able commandsfor $fullName (sort keys %rpcFunctions ) {    $rpc = $rpcFunctions{$fullName};    if ($rpc->{'provided'} == 0){	next;    }    if ($rpc->{'interfaceName'}){	if ( $componentName ne $rpc->{'componentName'} ||	     $interfaceName ne $rpc->{'interfaceName'} ) {	    $gparams = "";	    if ($rpc->{'gparams'}){		$gparams = "<";		for my $gparam (@{$rpc->{'gparams'}}) {		    $gparams .= $gparam;		}				$gparams .= ">";	    }	    $componentName = $rpc->{'componentName'};	    $interfaceName = $rpc->{'interfaceName'};	    $s = sprintf "%s    interface $rpc->{'interfaceType'}$gparams as $componentName\_$interfaceName;\n", $s;	}    }    else{	$params = $rpc->{'params'};	$s = sprintf "%s    $rpc->{'functionType'} $rpc->{'returnType'}->{'typeDecl'} $rpc->{'componentName'}_$rpc->{'functionName'} (  ", $s;	for ($count=0; $count < $rpc->{'numParams'} ; $count++)	{	    $s = sprintf "%s %s %s,", $s, $params->{"param$count"}->{'type'}->{'typeDecl'},  $params->{"param$count"}->{'name'};	}	$s = sprintf "%s\b );\n", $s;	    }}# build lists of the arguments and return sizesmy $num_rpcs = keys %rpcFunctions;my @rpc_args_sizes = ();my @rpc_return_sizes = ();for $fullName (sort keys %rpcFunctions) {  $rpc = $rpcFunctions{$fullName};  my @as = ();  for( my $n=0; $n < $rpc->{numParams} ; $n++ ) {    my $p = $rpc->{params}{"param$n"}{type}{typeName};    push( @as, "sizeof($p)" );  }      push( @rpc_args_sizes, join("+",@as) || "0" );  push( @rpc_return_sizes, "sizeof($rpc->{returnType}{typeName})" );}my $rpc_args_elems = "    " . join( ",\n    ", @rpc_args_sizes );my $rpc_return_elems = "    " . join( ",\n    ", @rpc_return_sizes );my $d = '%d';$s .=<<"EOF";  }}implementation {  TOS_Msg dripStore;  TOS_Msg cmdStore;  TOS_Msg responseMsgBuf;  TOS_MsgPtr responseMsgPtr;  uint16_t dripStoreLength;  uint16_t cmdStoreLength;  uint16_t queryID;  uint16_t returnAddress;  bool processingCommand;  bool sendingResponse;  static const uint8_t args_sizes[$num_rpcs] = {$rpc_args_elems  };  static const uint8_t return_sizes[$num_rpcs] = {$rpc_return_elems  };  command result_t StdControl.init() {    responseMsgPtr = &responseMsgBuf;    processingCommand=FALSE;    sendingResponse=FALSE;    call SubControl.init();    return SUCCESS;  }  command result_t StdControl.start() {    call SubControl.start();    call CommandDrip.init();    return SUCCESS;  }  command result_t StdControl.stop() {    return SUCCESS;  }  task void processCommand(){    RpcCommandMsg* msg = (RpcCommandMsg*)cmdStore.data;    uint8_t* byteSrc = msg->data;    uint16_t maxLength;    uint16_t id = msg->commandID;    RpcResponseMsg *responseMsg = (RpcResponseMsg*)call DrainSend.getBuffer(responseMsgPtr, &maxLength);    dbg(DBG_USR2, "processing command id %d, transaction %d\\n", msg->commandID, msg->transactionID);

⌨️ 快捷键说明

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