Browse Source

Merge branch 'cg_merges_20130822a' into bfgminer

Luke Dashjr 12 years ago
parent
commit
68d294000d
5 changed files with 253 additions and 59 deletions
  1. 2 2
      README
  2. 142 53
      README.RPC
  3. 2 2
      api.c
  4. 2 2
      miner.c
  5. 105 0
      miner.php

+ 2 - 2
README

@@ -175,8 +175,8 @@ Options for both config file and command line:
                     See --api-allow to overcome this
 --api-mcast         Enable API Multicast listener, default: disabled
 --api-mcast-addr <arg> API Multicast listen address (default: "224.0.0.75")
---api-mcast-code <arg> Code expected in the API Multicast (default: "FTW")
---api-mcast-port <arg> Port number of miner API Multicast listener (default: 4028)
+--api-mcast-code <arg> Code expected in the API Multicast message, don't use '-' (default: "FTW")
+--api-mcast-port <arg> API Multicast listen port (default: 4028)
 --api-network       Allow API (if enabled) to listen on/for any address (default: only 127.0.0.1)
 --api-port          Port number of miner API (default: 4028)
 --balance           Change multipool strategy from failover to even share balance

+ 142 - 53
README.RPC

@@ -32,6 +32,10 @@ Using the "--api-allow" option overrides the "--api-network" option if they
 are both specified
 With "--api-allow", 127.0.0.1 is not by default given access unless specified
 
+If you start BFGMiner also with the "--api-mcast" option, it will listen for
+a multicast message and reply to it with a message containing it's API port
+number, but only if the IP address of the sender is allowed API access
+
 More groups (like the privileged group W:) can be defined using the
 --api-groups command
 Valid groups are only the letters A-Z (except R & W are predefined) and are
@@ -42,7 +46,8 @@ To give an IP address/subnet access to a group you use the group letter
 in front of the IP address instead of W: e.g. P:192.168.0/32
 An IP address/subnet can only be a member of one group
 A sample API group would be:
- --api-groups P:switchpool:enablepool:addpool:disablepool:removepool:poolpriority:*
+ --api-groups
+        P:switchpool:enablepool:addpool:disablepool:removepool:poolpriority:*
 This would create a group 'P' that can do all current pool commands and all
 non-privileged commands - the '*' means all non-privileged commands
 Without the '*' the group would only have access to the pool commands
@@ -106,7 +111,7 @@ The STATUS section is:
 
 For API version 1.10 and later:
 
-The list of requests - a (*) means it requires privileged access - and replies are:
+The list of requests - a (*) means it requires privileged access - and replies:
 
  Request       Reply Section  Details
  -------       -------------  -------
@@ -122,7 +127,8 @@ The list of requests - a (*) means it requires privileged access - and replies a
                               ADL in use=X, <- Y or N if any GPU has ADL
                               Strategy=Name, <- the current pool strategy
                               Log Interval=N, <- log interval (--log N)
-                              Device Code=GPU ICA , <- spaced list of compiled devices
+                              Device Code=GPU ICA , <- spaced list of compiled
+                                                       device drivers
                               OS=Linux/Apple/..., <- operating System
                               Failover-Only=true/false, <- failover-only setting
                               ScanTime=N, <- --scan-time setting
@@ -132,15 +138,15 @@ The list of requests - a (*) means it requires privileged access - and replies a
  summary       SUMMARY        The status summary of the miner
                               e.g. Elapsed=NNN,Found Blocks=N,Getworks=N,...|
 
- pools         POOLS          The status of each pool
-                              e.g. Pool=0,URL=http://pool.com:6311,Status=Alive,...|
+ pools         POOLS          The status of each pool e.g.
+                              Pool=0,URL=http://pool.com:6311,Status=Alive,...|
 
  devs          DEVS           Each available GPU, PGA and CPU with their status
                               e.g. GPU=0,Accepted=NN,MHS av=NNN,...,Intensity=D|
-                              Last Share Time=NNN, <- standard long time in seconds
+                              Last Share Time=NNN, <- standard long time in sec
                                (or 0 if none) of last accepted share
                               Last Share Pool=N, <- pool number (or -1 if none)
-                              Last Valid Work=NNN, <- standand long time in seconds
+                              Last Valid Work=NNN, <- standand long time in sec
                                of last work returned that wasn't an HW:
                               Will not report PGAs if PGA mining is disabled
                               Will not report CPUs if CPU mining is disabled
@@ -158,7 +164,8 @@ The list of requests - a (*) means it requires privileged access - and replies a
  pga|N         PGA            The details of a single PGA number N in the same
                               format and details as for DEVS
                               This is only available if PGA mining is enabled
-                              Use 'pgacount' or 'config' first to see if there are any
+                              Use 'pgacount' or 'config' first to see if there
+                              are any
 
  cpu|N         CPU            The details of a single CPU number N in the same
                               format and details as for DEVS
@@ -233,19 +240,23 @@ The list of requests - a (*) means it requires privileged access - and replies a
 
  gpuintensity|N,I (*)
                none           There is no reply section just the STATUS section
-                              stating the results of setting GPU N intensity to I
+                              stating the results of setting GPU N intensity
+                              to I
 
  gpumem|N,V (*)
                none           There is no reply section just the STATUS section
-                              stating the results of setting GPU N memoryclock to V MHz
+                              stating the results of setting GPU N memoryclock
+                              to V MHz
 
  gpuengine|N,V (*)
                none           There is no reply section just the STATUS section
-                              stating the results of setting GPU N clock to V MHz
+                              stating the results of setting GPU N clock
+                              to V MHz
 
  gpufan|N,V (*)
                none           There is no reply section just the STATUS section
-                              stating the results of setting GPU N fan speed to V%
+                              stating the results of setting GPU N fan speed
+                              to V%
 
  gpuvddc|N,V (*)
                none           There is no reply section just the STATUS section
@@ -253,21 +264,23 @@ The list of requests - a (*) means it requires privileged access - and replies a
 
  save|filename (*)
                none           There is no reply section just the STATUS section
-                              stating success or failure saving the BFGMiner config
-                              to filename
+                              stating success or failure saving the BFGMiner
+                              config to filename
                               The filename is optional and will use the BFGMiner
                               default if not specified
 
  quit (*)      none           There is no status section but just a single "BYE"
                               reply before BFGMiner quits
 
- notify        NOTIFY         The last status and history count of each devices problem
+ notify        NOTIFY         The last status and history count of each devices
+                              problem
                               e.g. NOTIFY=0,Name=PGA,ID=0,ProcID=0,Last Well=1332432290,...|
 
  privileged (*)
                none           There is no reply section just the STATUS section
-                              stating an error if you do not have privileged access
-                              to the API and success if you do have privilege
+                              stating an error if you do not have privileged
+                              access to the API and success if you do have
+                              privilege
                               The command doesn't change anything in BFGMiner
 
  pgaenable|N (*)
@@ -285,25 +298,28 @@ The list of requests - a (*) means it requires privileged access - and replies a
                none           There is no reply section just the STATUS section
                               stating the results of the identify request
                               This is only available if PGA mining is enabled
-                              and currently only BitForce Singles support this command
-                              On a BitForce Single it will flash the led on the front
-                              of the device for approximately 4s
-                              All other non-BFL PGA devices will return a warning
-                              status message stating that they don't support it
-                              This adds a 4s delay to the BFL share being processed
-                              so you may get a message stating that processing took
-                              longer than 7000ms if the request was sent towards
-                              the end of the timing of any work being worked on
+                              and currently only BitForce Singles support this
+                              command
+                              On a BitForce Single it will flash the led on the
+                              front of the device for approximately 4s
+                              All other non-BFL PGA devices will return a
+                              warning status message stating that they don't
+                              support it
+                              This adds a 4s delay to the BFL share being
+                              processed so you may get a message stating that
+                              processing took longer than 7000ms if the request
+                              was sent towards the end of the timing of any work
+                              being worked on
                               e.g.: BFL0: took 8438ms - longer than 7000ms
                               You should ignore this
 
  devdetails    DEVDETAILS     Each device with a list of their static details
-                              This lists all devices including those not supported
-                              by the 'devs' command
+                              This lists all devices including those not
+                              supported by the 'devs' command
                               e.g. DEVDETAILS=0,Name=PGA,ID=0,ProcID=0,Driver=bitforce,...|
 
- restart (*)   none           There is no status section but just a single "RESTART"
-                              reply before BFGMiner restarts
+ restart (*)   none           There is no status section but just a single
+                              "RESTART" reply before BFGMiner restarts
 
  stats         STATS          Each device or pool that has 1 or more getworks
                               with a list of stats regarding getwork times
@@ -328,12 +344,13 @@ The list of requests - a (*) means it requires privileged access - and replies a
 
  debug|setting (*)
                DEBUG          Debug settings
-                              The optional commands for 'setting' are the same as
-                              the screen curses debug settings
+                              The optional commands for 'setting' are the same
+                              as the screen curses debug settings
                               You can only specify one setting
-                              Only the first character is checked (case insensitive):
-                              Silent, Quiet, Verbose, Debug, RPCProto, PerDevice,
-                              WorkTime, Normal
+                              Only the first character is checked - case
+                              insensitive:
+                              Silent, Quiet, Verbose, Debug, RPCProto,
+                              PerDevice, WorkTime, Normal
                               The output fields are (as above):
                               Silent=true/false,
                               Quiet=true/false,
@@ -353,30 +370,34 @@ The list of requests - a (*) means it requires privileged access - and replies a
 
  pgaset|N,opt[,val] (*)
                none           There is no reply section just the STATUS section
-                              stating the results of setting PGA N with opt[,val]
+                              stating the results of setting PGA N with
+                              opt[,val]
                               This is only available if PGA mining is enabled
 
-                              If the PGA does not support any set options, it will
-                              always return a WARN stating pgaset isn't supported
+                              If the PGA does not support any set options, it
+                              will always return a WARN stating pgaset isn't
+                              supported
 
                               If opt=help it will return an INFO status with a
                               help message about the options available
 
                               The current options are:
-                               MMQ opt=clock val=2 to 250 (and a multiple of 2)
-                               XBS opt=clock val=2 to 250 (and a multiple of 2)
+                               MMQ opt=clock val=2 to 250 (a multiple of 2)
+                               XBS opt=clock val=2 to 250 (a multiple of 2)
 
  zero|Which,true/false (*)
                none           There is no reply section just the STATUS section
-                              stating that the zero, and optional summary, was done
-                              If Which='all', all normal cgminer and API statistics
-                              will be zeroed other than the numbers displayed by the
-                              usbstats and stats commands
+                              stating that the zero, and optional summary, was
+                              done
+                              If Which='all', all normal cgminer and API
+                              statistics will be zeroed other than the numbers
+                              displayed by the usbstats and stats commands
                               If Which='bestshare', only the 'Best Share' values
-                              are zeroed for each pool and the global 'Best Share'
-                              The true/false option determines if a full summary is
-                              shown on the cgminer display like is normally displayed
-                              on exit.
+                              are zeroed for each pool and the global
+                              'Best Share'
+                              The true/false option determines if a full summary
+                              is shown on the cgminer display like is normally
+                              displayed on exit.
 
 When you enable, disable or restart a GPU or PGA, you will also get Thread
 messages in the BFGMiner status window.
@@ -908,6 +929,22 @@ to
 See --api-network or --api-allow for more access details
 and how to give write access
 
+You can however, also tell miner.php to find your mining rigs automatically
+on the local subnet
+
+Add the following to each BFGMiner:
+
+ --api-mcast
+
+or in your bfgminer.conf
+
+ "api-mcast" : true,
+
+And in miner.php set $mcast = true;
+
+This will ignore the value of $rigs and overwrite it with the list of zero or
+more rigs found on the network in the timout specified
+
 ---------
 
 Once you have a web server with PHP running
@@ -993,7 +1030,8 @@ the last one
 
 So an example for 3 rigs would be:
 
- $rigs = array('192.168.0.100:4028:A', '192.168.0.102:4028:B', '192.168.0.110:4028:C');
+ $rigs = array('192.168.0.100:4028:A', '192.168.0.102:4028:B',
+               '192.168.0.110:4028:C');
 
 Of course each of the rigs listed would also have to have the API
 running and be set to allow the web server to access the API - as
@@ -1140,6 +1178,54 @@ e.g. $rigs = array('127.0.0.1:4028','myrig.com:4028:Sugoi');
 
 ---------
 
+Default:
+ $mcast = false;
+
+Set $mcast to true to look for your rigs and ignore $rigs
+
+---------
+
+Default:
+ $mcastaddr = '224.0.0.75';
+
+API Multicast address all miners are listening on
+
+---------
+
+Default:
+ $mcastport = 4028;
+
+API Multicast UDP port all miners are listening on
+
+---------
+
+Default:
+ $mcastcode = 'FTW';
+
+The code all miners expect in the Multicast message sent
+The message sent is "cgm-code-listport"
+Don't use the '-' character if you change it
+
+---------
+
+Default:
+ $mcastlistport = 4027;
+
+UDP port number that is added to the broadcast message sent
+that specifies to the miners the port to reply on
+
+---------
+
+Default:
+ $mcasttimeout = 1.5;
+
+Set $mcasttimeout to the number of seconds (floating point)
+to wait for replies to the Multicast message
+N.B. the accuracy of the timing used to wait for the replies is
+~0.1s so there's no point making it more than one decimal place
+
+---------
+
 Default:
  $rigipsecurity = true;
 
@@ -1319,11 +1405,14 @@ Looking at the Mobile example:
 			'DEVS.Temperature=Temp', 'DEVS.MHS av=MHS av',
 			'DEVS.Accepted=Accept', 'DEVS.Rejected=Rej',
 			'DEVS.Utility=Utility', 'NOTIFY.Last Not Well=Not Well'),
-  'POOL' => array('POOL', 'Status', 'Accepted', 'Rejected=Rej', 'Last Share Time'));
+  'POOL' => array('POOL', 'Status', 'Accepted', 'Rejected=Rej',
+                  'Last Share Time'));
 
  $mobilesum = array(
-  'SUMMARY' => array('MHS av', 'Found Blocks', 'Accepted', 'Rejected', 'Utility'),
-  'DEVS+NOTIFY' => array('DEVS.MHS av', 'DEVS.Accepted', 'DEVS.Rejected', 'DEVS.Utility'),
+  'SUMMARY' => array('MHS av', 'Found Blocks', 'Accepted', 'Rejected',
+                     'Utility'),
+  'DEVS+NOTIFY' => array('DEVS.MHS av', 'DEVS.Accepted', 'DEVS.Rejected',
+                         'DEVS.Utility'),
   'POOL' => array('Accepted', 'Rejected'));
 
  $customsummarypages = array('Mobile' => array($mobilepage, $mobilesum));
@@ -1459,5 +1548,5 @@ The first 4 are as expected - the numerical sum, average, minimum or maximum
 'count' is the number of rows in the section specified in the calc e.g.
  ('DEVS.Name' => 'count') would be the number of DEVS selected in the 'where'
  of course any valid 'DEVS.Xyz' would give the same 'count' value
-'any' is effectively random: the field value in the first row of the grouped data
+'any' is effectively random: the field value in the 1st row of the grouped data
 An unrecognised 'function' uses 'any'

+ 2 - 2
api.c

@@ -3800,10 +3800,10 @@ static void mcast()
 						0, (struct sockaddr *)(&came_from),
 						sizeof(came_from));
 				if (SOCKETFAIL(rep)) {
-					applog(LOG_DEBUG, "API mcast reply failed (%s) (%d)",
+					applog(LOG_DEBUG, "API mcast send reply failed (%s) (%d)",
 								SOCKERRMSG, (int)reply_sock);
 				} else {
-					applog(LOG_DEBUG, "API mcast reply (%s) succeeded (%d) (%d)",
+					applog(LOG_DEBUG, "API mcast send reply (%s) succeeded (%d) (%d)",
 								replybuf, (int)rep, (int)reply_sock);
 				}
 

+ 2 - 2
miner.c

@@ -1374,10 +1374,10 @@ static struct opt_table opt_config_table[] = {
 		     "API Multicast listen address"),
 	OPT_WITH_ARG("--api-mcast-code",
 		     opt_set_charp, opt_show_charp, &opt_api_mcast_code,
-		     "Code expected in the API Multicast"),
+		     "Code expected in the API Multicast message, don't use '-'"),
 	OPT_WITH_ARG("--api-mcast-port",
 		     set_int_1_to_65535, opt_show_intval, &opt_api_mcast_port,
-		     "Port number of miner API Multicast listener"),
+		     "API Multicast listen port"),
 	OPT_WITHOUT_ARG("--api-network",
 			opt_set_bool, &opt_api_network,
 			"Allow API (if enabled) to listen on/for any address, default: only 127.0.0.1"),

+ 105 - 0
miner.php

@@ -3,6 +3,8 @@ session_start();
 date_default_timezone_set(@date_default_timezone_get());
 #
 global $title, $miner, $port, $readonly, $notify, $rigs;
+global $mcast, $mcastaddr, $mcastport, $mcastcode;
+global $mcastlistport, $mcasttimeout;
 global $rigipsecurity, $rigtotals, $forcerigtotals;
 global $socksndtimeoutsec, $sockrcvtimeoutsec;
 global $checklastshare, $poolinputs, $hidefields;
@@ -44,6 +46,25 @@ $poolinputs = false;
 #  format: 'IP:Port' or 'Host:Port' or 'Host:Port:Name'
 $rigs = array('127.0.0.1:4028');
 #
+# Set $mcast to true to look for your rigs and ignore $rigs
+$mcast = false;
+#
+# API Multicast address all cgminers are listening on
+$mcastaddr = '224.0.0.75';
+#
+# API Multicast UDP port all cgminers are listening on
+$mcastport = 4028;
+#
+# The code all cgminers expect in the Multicast message sent
+$mcastcode = 'FTW';
+#
+# UDP port cgminers are to reply on (by request)
+$mcastlistport = 4027;
+#
+# Set $mcasttimeout to the number of seconds (floating point)
+# to wait for replies to the Multicast message
+$mcasttimeout = 1.5;
+#
 # Set $rigipsecurity to false to show the IP/Port of the rig
 # in the socket error messages and also show the full socket message
 $rigipsecurity = true;
@@ -320,6 +341,88 @@ global $haderror, $error;
 $haderror = false;
 $error = null;
 #
+function getrigs()
+{
+ global $rigs, $mcastaddr, $mcastport, $mcastcode, $mcasttimeout, $error;
+
+ $listname = "0.0.0.0";
+
+ $rigs = array();
+
+ $rep_soc = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
+ if ($rep_soc === false || $rep_soc == null)
+ {
+	$msg = "ERR: mcast listen socket create(UDP) failed";
+	if ($rigipsecurity === false)
+	{
+		$error = socket_strerror(socket_last_error());
+		$error = "$msg '$error'\n";
+	}
+	else
+		$error = "$msg\n";
+
+	return;
+ }
+
+ $res = socket_bind($rep_soc, $listname, $mcastlistport);
+ if ($res === false)
+ {
+	$msg1 = "ERR: mcast listen socket bind(";
+	$msg2 = ") failed";
+	if ($rigipsecurity === false)
+	{
+		$error = socket_strerror(socket_last_error());
+		$error = "$msg1$listname,$mcastlistport$msg2 '$error'\n";
+	}
+	else
+		$error = "$msg1$msg2\n";
+
+	socket_close($rep_soc);
+	return;
+ }
+
+ $mcast_soc = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
+ if ($mcast_soc === false || $mcast_soc == null)
+ {
+	$msg = "ERR: mcast send socket create(UDP) failed";
+	if ($rigipsecurity === false)
+	{
+		$error = socket_strerror(socket_last_error());
+		$error = "$msg '$error'\n";
+	}
+	else
+		$error = "$msg\n";
+
+	socket_close($rep_soc);
+	return;
+ }
+
+ $buf = "cgminer-$mcastcode-$mcastlistport";
+ socket_sendto($mcast_soc, $buf, strlen($buf), 0, $mcastaddr, $mcastport);
+ socket_close($mcast_soc);
+
+ $stt = microtime(true);
+ while (true)
+ {
+	$got = @socket_recvfrom($rep_soc, $buf, 32, MSG_DONTWAIT, $ip, $p);
+	if ($got !== false && $got > 0)
+	{
+		$ans = explode('-', $buf);
+		if (count($ans) == 3 && $ans[0] == 'cgm' && $ans[1] == 'FTW')
+		{
+			$rp = intval($ans[2]);
+			$rigs[] = "$ip:$rp";
+		}
+	}
+	if ((microtime(true) - $stt) >= $mcasttimeout)
+		break;
+
+	usleep(100000);
+ }
+
+ socket_close($rep_soc);
+}
+#
 function getsock($rig, $addr, $port)
 {
  global $rigipsecurity;
@@ -2788,6 +2891,8 @@ function display()
 	pagebuttons(null, null);
 }
 #
+if (isset($mcast) && $mcast === true)
+ getrigs();
 display();
 #
 ?>