Initiate stratum and grab first json result.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
diff --git a/cgminer.c b/cgminer.c
index 000782c..63412c1 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -557,6 +557,8 @@ static char *set_url(char *arg)
if (!extract_sockaddr(pool, arg))
return "Failed to extract address from parsed url";
+ initiate_stratum(pool);
+
opt_set_charp(arg, &pool->rpc_url);
if (strncmp(arg, "http://", 7) &&
strncmp(arg, "https://", 8)) {
diff --git a/util.c b/util.c
index 6ac8064..79c7e8f 100644
--- a/util.c
+++ b/util.c
@@ -845,3 +845,96 @@ bool extract_sockaddr(struct pool *pool, char *url)
pool->server = (struct sockaddr_in *)res->ai_addr;
return true;
}
+
+static bool sock_send(int sock, char *s, ssize_t len)
+{
+ size_t sent = 0;
+
+ while (len > 0 ) {
+ sent = send(sock, s + sent, len, 0);
+ if (sent < 1)
+ return false;
+ len -= sent;
+ }
+ fsync(sock);
+
+ return true;
+}
+
+#define RECVSIZE 8192
+
+bool initiate_stratum(struct pool *pool)
+{
+ json_t *val, *res_val, *err_val;
+ struct timeval timeout;
+ char *s, *ret = NULL;
+ json_error_t err;
+ ssize_t len;
+ fd_set rd;
+
+ s = alloca(RECVSIZE);
+ sprintf(s, "{\"id\": 0, \"method\": \"mining.subscribe\", \"params\": []}\n");
+
+ pool->sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (pool->sock == INVSOCK)
+ quit(1, "Failed to create pool socket in initiate_stratum");
+ if (SOCKETFAIL(connect(pool->sock, (struct sockaddr *)pool->server, sizeof(struct sockaddr)))) {
+ applog(LOG_DEBUG, "Failed to connect socket to pool");
+ return false;
+ }
+
+ if (!sock_send(pool->sock, s, strlen(s))) {
+ applog(LOG_DEBUG, "Failed to send s in initiate_stratum");
+ return false;
+ }
+
+ /* Use select to timeout instead of waiting forever for a response */
+ FD_ZERO(&rd);
+ FD_SET(pool->sock, &rd);
+ timeout.tv_sec = 60;
+ if (select(pool->sock + 1, &rd, NULL, NULL, &timeout) < 1) {
+ applog(LOG_DEBUG, "Timed out waiting for response in initiate_stratum");
+ return false;
+ }
+
+ if (recv(pool->sock, s, RECVSIZE, MSG_PEEK | MSG_DONTWAIT) < 1) {
+ applog(LOG_DEBUG, "Failed to recv sock in initiate_stratum");
+ return false;
+ }
+
+ ret = strtok(s, "\n");
+ if (!ret) {
+ applog(LOG_DEBUG, "Failed to parse a \\n terminated string in initiate_stratum");
+ return false;
+ }
+
+ len = strlen(ret);
+ read(pool->sock, s, len);
+
+ val = JSON_LOADS(s, &err);
+ if (!val) {
+ applog(LOG_DEBUG, "JSON decode failed(%d): %s", err.line, err.text);
+ return false;
+ }
+
+ res_val = json_object_get(val, "result");
+ err_val = json_object_get(val, "error");
+
+ if (!res_val || json_is_null(res_val) ||
+ (err_val && !json_is_null(err_val))) {
+ char *ss;
+
+ if (err_val)
+ ss = json_dumps(err_val, JSON_INDENT(3));
+ else
+ ss = strdup("(unknown reason)");
+
+ applog(LOG_INFO, "JSON-RPC call failed: %s", ss);
+
+ free(ss);
+
+ return false;
+ }
+
+ return true;
+}
diff --git a/util.h b/util.h
index c99ecfd..72304fe 100644
--- a/util.h
+++ b/util.h
@@ -110,5 +110,6 @@
#endif
struct pool;
bool extract_sockaddr(struct pool *pool, char *url);
+bool initiate_stratum(struct pool *pool);
#endif /* __UTIL_H__ */