Example #1
0
void extint_w2a(void *param)
{
	int n, i, j;
	conn_t *conn = (conn_t *) param;
	u4_t ka_time = timer_sec();
	
	// initialize extension for this connection
	send_msg_mc(conn->mc, false, "EXT ext_client_init");
	
	nbuf_t *nb = NULL;
	while (TRUE) {
		int rx_chan, ext_rx_chan;
		ext_t *ext;
	
		if (nb) web_to_app_done(conn, nb);
		n = web_to_app(conn, &nb);
				
		if (n) {
			char *cmd = nb->buf;
			cmd[n] = 0;		// okay to do this -- see nbuf.c:nbuf_allocq()
			char id[64];

			ka_time = timer_sec();

			// receive and send a roundtrip keepalive
			i = strcmp(cmd, "SET keepalive");
			if (i == 0) {
				ext_send_msg(conn->ext_rx_chan, false, "EXT keepalive");
				continue;
			}

			ext_rx_chan = conn->ext_rx_chan;
			//printf("extint_w2a: %s CONN%d-%p RX%d-%p %d <%s>\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn, strlen(cmd), cmd);

			// answer from client ext about who they are
			// match against list of known extensions and register msg handler
			char client[32];
			int first_time;
			i = sscanf(cmd, "SET ext_switch_to_client=%s first_time=%d rx_chan=%d", client, &first_time, &rx_chan);
			if (i == 3) {
				for (i=0; i < n_exts; i++) {
					ext = ext_list[i];
					if (strcmp(client, ext->name) == 0) {
						//printf("ext_switch_to_client: found func %p CONN%d-%p for ext %s RX%d\n", ext->receive_msgs, conn->self_idx, conn, client, rx_chan);
						ext_users[rx_chan].ext = ext;
						ext_users[rx_chan].conn = conn;
						conn->ext_rx_chan = rx_chan;
						conn->ext = ext;
						TaskNameS(ext->name);
						break;
					}
				}
				if (i == n_exts) panic("ext_switch_to_client: unknown ext");

				// automatically let extension server-side know the connection has been established and
				// our stream thread is running
				if (first_time)
					ext->receive_msgs((char *) "SET ext_server_init", rx_chan);
				continue;
			}
			
			i = sscanf(cmd, "SET ext_blur=%d", &rx_chan);
			if (i == 1) {
				extint_ext_users_init(rx_chan);
				continue;
			}
			
			i = strcmp(cmd, "SET init");
			if (i == 0) {
				continue;
			}

			i = sscanf(cmd, "SERVER DE CLIENT %s", id);
			if (i == 1) {
				continue;
			}
			
			ext_rx_chan = conn->ext_rx_chan;
			if (ext_rx_chan == -1) {
				printf("### extint_w2a: %s CONN%d-%p ext_rx_chan == -1?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn);
				continue;
			}
			ext = ext_users[ext_rx_chan].ext;
			if (ext == NULL) {
				printf("### extint_w2a: %s CONN%d-%p ext_rx_chan %d ext NULL?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan);
				continue;
			}
			if (ext->receive_msgs) {
				//printf("extint_w2a: %s ext->receive_msgs() %p CONN%d-%p RX%d-%p %d <%s>\n", conn->ext? conn->ext->name:"?", ext->receive_msgs, conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn, strlen(cmd), cmd);
				if (ext->receive_msgs(cmd, ext_rx_chan))
					continue;
			} else {
				printf("### extint_w2a: %s CONN%d-%p RX%d-%p ext->receive_msgs == NULL?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn);
				continue;
			}
			
			printf("extint_w2a: %s CONN%d-%p unknown command: <%s> ======================================================\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, cmd);
			continue;
		}
		
		conn->keep_alive = timer_sec() - ka_time;
		bool keepalive_expired = (conn->keep_alive > KEEPALIVE_SEC);
		if (keepalive_expired) {
			ext_rx_chan = conn->ext_rx_chan;
			ext = ext_users[ext_rx_chan].ext;
			printf("EXT KEEP-ALIVE EXPIRED RX%d %s\n", ext_rx_chan, ext? ext->name : "(no ext)");
			if (ext != NULL && ext->close_conn != NULL)
				ext->close_conn(ext_rx_chan);
			extint_ext_users_init(ext_rx_chan);
			rx_server_remove(conn);
			panic("shouldn't return");
		}

		TaskSleep(250000);
	}
}
Example #2
0
void w2a_admin(void *param)
{
	int n, i, j;
	conn_t *conn = (conn_t *) param;
	static char json_buf[16384];
	u4_t ka_time = timer_sec();
	
	// send initial values
	send_msg(conn, SM_NO_DEBUG, "ADM init=%d", RX_CHANS);
	
	nbuf_t *nb = NULL;
	while (TRUE) {
	
		if (nb) web_to_app_done(conn, nb);
		n = web_to_app(conn, &nb);
				
		if (n) {
			char *cmd = nb->buf;
			cmd[n] = 0;		// okay to do this -- see nbuf.c:nbuf_allocq()

			ka_time = timer_sec();

			if (rx_common_cmd("W/F", conn, cmd))
				continue;
			
			//printf("ADMIN: %d <%s>\n", strlen(cmd), cmd);

			i = strcmp(cmd, "SET init");
			if (i == 0) {
				continue;
			}

			i = strcmp(cmd, "SET gps_update");
			if (i == 0) {
				gps_stats_t::gps_chan_t *c;
				
				char *cp = json_buf;
				n = sprintf(cp, "{ \"FFTch\":%d, \"ch\":[ ", gps.FFTch); cp += n;
				
				for (i=0; i < gps_chans; i++) {
					c = &gps.ch[i];
					int un = c->ca_unlocked;
					n = sprintf(cp, "%s{ \"ch\":%d, \"prn\":%d, \"snr\":%d, \"rssi\":%d, \"gain\":%d, \"hold\":%d, \"wdog\":%d"
						", \"unlock\":%d, \"parity\":%d, \"sub\":%d, \"sub_renew\":%d, \"novfl\":%d }",
						i? ", ":"", i, c->prn, c->snr, c->rssi, c->gain, c->hold, c->wdog,
						un, c->parity, c->sub, c->sub_renew, c->novfl); cp += n;
					c->parity = 0;
					for (j = 0; j < SUBFRAMES; j++) {
						if (c->sub_renew & (1<<j)) {
							c->sub |= 1<<j;
							c->sub_renew &= ~(1<<j);
						}
					}
				}

				n = sprintf(cp, " ]"); cp += n;

				UMS hms(gps.StatSec/60/60);
				
				unsigned r = (timer_ms() - gps.start)/1000;
				if (r >= 3600) {
					n = sprintf(cp, ", \"run\":\"%d:%02d:%02d\"", r / 3600, (r / 60) % 60, r % 60); cp += n;
				} else {
					n = sprintf(cp, ", \"run\":\"%d:%02d\"", (r / 60) % 60, r % 60); cp += n;
				}

				if (gps.ttff) {
					n = sprintf(cp, ", \"ttff\":\"%d:%02d\"", gps.ttff / 60, gps.ttff % 60); cp += n;
				} else {
					n = sprintf(cp, ", \"ttff\":null"); cp += n;
				}

				if (gps.StatDay != -1) {
					n = sprintf(cp, ", \"gpstime\":\"%s %02d:%02d:%02.0f\"", Week[gps.StatDay], hms.u, hms.m, hms.s); cp += n;
				} else {
					n = sprintf(cp, ", \"gpstime\":null"); cp += n;
				}

				if (gps.StatLat) {
					n = sprintf(cp, ", \"lat\":\"%8.6f %c\"", gps.StatLat, gps.StatNS); cp += n;
					n = sprintf(cp, ", \"lon\":\"%8.6f %c\"", gps.StatLon, gps.StatEW); cp += n;
					n = sprintf(cp, ", \"alt\":\"%1.0f m\"", gps.StatAlt); cp += n;
					n = sprintf(cp, ", \"map\":\"<a href='http://wikimapia.org/#lang=en&lat=%8.6f&lon=%8.6f&z=18&m=b' target='_blank'>wikimapia.org</a>\"",
						gps.sgnLat, gps.sgnLon); cp += n;
				} else {
					n = sprintf(cp, ", \"lat\":null"); cp += n;
				}
					
				n = sprintf(cp, ", \"acq\":%d, \"track\":%d, \"good\":%d, \"fixes\":%d, \"adc_clk\":%.6f, \"adc_corr\":%d",
					gps.acquiring? 1:0, gps.tracking, gps.good, gps.fixes, (adc_clock - adc_clock_offset)/1e6, gps.adc_clk_corr); cp += n;

				n = sprintf(cp, " }"); cp += n;
				send_encoded_msg_mc(conn->mc, "ADM", "gps_update", "%s", json_buf);

				continue;
			}

			i = strcmp(cmd, "SET sdr_hu_update");
			if (i == 0) {
				gps_stats_t::gps_chan_t *c;
				
				char *cp = json_buf;
				n = sprintf(cp, "{ "); cp += n;
				if (gps.StatLat) {
					n = sprintf(cp, "\"lat\":\"%8.6f\", \"lon\":\"%8.6f\"",
						gps.sgnLat, gps.sgnLon); cp += n;
				}
				n = sprintf(cp, " }"); cp += n;
				send_encoded_msg_mc(conn->mc, "ADM", "sdr_hu_update", "%s", json_buf);

				continue;
			}

			int force_check;
			i = sscanf(cmd, "SET force_check=%d force_build=%d", &force_check, &force_build);
			if (i == 2) {
				check_for_update(force_check);
				continue;
			}

			i = strcmp(cmd, "SET reload_index_params");
			if (i == 0) {
				reload_index_params();
				continue;
			}

			i = strcmp(cmd, "SET extint_load_extension_configs");
			if (i == 0) {
				extint_load_extension_configs(conn);
				continue;
			}

			i = strcmp(cmd, "SET restart");
			if (i == 0) {
				lprintf("ADMIN: restart requested by admin..\n");
				exit(0);
			}

			i = strcmp(cmd, "SET reboot");
			if (i == 0) {
				lprintf("ADMIN: reboot requested by admin..\n");
				system("reboot");
				while (true)
					usleep(100000);
			}

			i = strcmp(cmd, "SET power_off");
			if (i == 0) {
				lprintf("ADMIN: power off requested by admin..\n");
				system("poweroff");
				while (true)
					usleep(100000);
			}

			printf("ADMIN: unknown command: <%s>\n", cmd);
			continue;
		}
		
		conn->keep_alive = timer_sec() - ka_time;
		bool keepalive_expired = (conn->keep_alive > KEEPALIVE_SEC);
		if (keepalive_expired) {
			printf("ADMIN KEEP-ALIVE EXPIRED\n");
			rx_server_remove(conn);
			return;
		}

		TaskSleep(250000);
	}
}
int main(int argc, char **argv) {

  int i,j,k,iad;
  int aad,bad,cad;
  int N=16;

  if(argc>1) {
    N=atoi(argv[1]);
  }

  i=N/4;
  if(N>(i*4)) N=(i+1)*4;

  double l2=log(N)/log(2.0);
  int il2=(int)l2;
  if(il2<l2) il2++;
  int MSZ=pow(2,il2);
  int N4=N/4;

  printf("N=%d; N/4=%d; msize=%d\n",N,N4,MSZ);

// actual memory allocation must be power of 2 although N can be any multiple of 4
  float *a=(float *)_mm_malloc(MSZ*MSZ*sizeof(float),128);
  float *b=(float *)_mm_malloc(MSZ*MSZ*sizeof(float),128);
  float *c=(float *)_mm_malloc(MSZ*MSZ*sizeof(float),128);

  int iv=0;
#pragma omp parallel for private (i,j,iv,iad)
  for(i=0; i<N; i++) {
    for(j=0; j<N; j++) {
      iv=j+i*N;
      iad=zorder2d(j,i);
      a[iad]=b[iad]=iv;
      c[iad]=0;
    }
  }

  tv ts;
  timer_reset(ts);
  timer_start(ts);

  for(i=0; i<N4; i++) {
#pragma omp parallel for private (aad,bad,cad,i,j,k)
    for(j=0; j<N4; j++) {
      cad=16*zorder2d(j,i);
      for(k=0; k<N4; k++) {
	aad=16*zorder2d(k,i);
	bad=16*zorder2d(j,k);
	zmatmul(&a[aad],&b[bad],&c[cad]);
      }
    }
  }
  timer_stop(ts);
  printf("sec: %lf\n",timer_sec(ts));
  float fN=N;
  printf("GFlops/s: %lf\n",(double)(fN*fN*(2*fN-1))/timer_sec(ts)/1000000000.0);

//  pmat(N,a);
//  pmat(N,b);
//  pmat(N,c);


  _mm_free(a);
  _mm_free(b);
  _mm_free(c);

}
Example #4
0
static void ll_printf(u4_t type, conn_t *c, const char *fmt, va_list ap)
{
	int i, sl;
	char *s, *cp;
	#define VBUF 1024
	
	if (!do_sdr) {
	//if (!background_mode) {
		if ((buf = (char*) malloc(VBUF)) == NULL)
			panic("log malloc");
		vsnprintf(buf, VBUF, fmt, ap);

		// remove our override and call the actual underlying printf
		#undef printf
			printf("%s", buf);
		#define printf ALT_PRINTF
		
		evPrintf(EC_EVENT, EV_PRINTF, -1, "printf", buf);
	
		if (buf) free(buf);
		buf = 0;
		return;
	}
	
	if (appending) {
		s = last_s;
	} else {
		brem = VBUF;
		if ((buf = (char*) malloc(VBUF)) == NULL)
			panic("log malloc");
		s = buf;
		start_s = s;
	}

	vsnprintf(s, brem, fmt, ap);
	sl = strlen(s);		// because vsnprintf returns length disregarding limit, not the actual length
	brem -= sl+1;
	
	cp = &s[sl-1];
	if (*cp != '\n' && brem && !(type & PRINTF_MSG)) {
		last_s = cp+1;
		appending = true;
		return;
	} else {
		appending = false;
	}
	
	// for logging, don't print an empty line at all
	if ((type & (PRINTF_REG | PRINTF_LOG)) && (!background_mode || strcmp(start_s, "\n") != 0)) {

		// remove non-ASCII since "systemctl status" gives [blob] message
		// unlike "systemctl log" which prints correctly
		int sl = strlen(buf);
		for (i=0; i < sl; i++)
			if (buf[i] > 0x7f) buf[i] = '?';

		char up_chan_stat[64], *s = up_chan_stat;
		
		// uptime
		u4_t up = timer_sec();
		u4_t sec = up % 60; up /= 60;
		u4_t min = up % 60; up /= 60;
		u4_t hr  = up % 24; up /= 24;
		u4_t days = up;
		if (days)
			sl = sprintf(s, "%dd:%02d:%02d:%02d ", days, hr, min, sec);
		else
			sl = sprintf(s, "%d:%02d:%02d ", hr, min, sec);
		s += sl;
	
		// show state of all rx channels
		rx_chan_t *rx;
		for (rx = rx_chan, i=0; rx < &rx_chan[RX_CHANS]; rx++, i++) {
			*s++ = rx->busy? '0'+i : '.';
		}
		*s++ = ' ';
		
		// show rx channel number if message is associated with a particular rx channel
		if (c != NULL) {
			for (i=0; i < RX_CHANS; i++)
				*s++ = (i == c->rx_channel)? '0'+i : ' ';
		} else {
			for (i=0; i < RX_CHANS; i++) *s++ = ' ';
		}
		*s = 0;
		
		if (((type & PRINTF_LOG) && (background_mode || log_foreground_mode)) || log_ordinary_printfs) {
			syslog(LOG_INFO, "%s %s", up_chan_stat, buf);
		}
	
		time_t t;
		char tb[32];
		time(&t);
		ctime_r(&t, tb);
		tb[24]=0;
		
		// remove our override and call the actual underlying printf
		#undef printf
			printf("%s %s %s", tb, up_chan_stat, buf);
		#define printf ALT_PRINTF

		evPrintf(EC_EVENT, EV_PRINTF, -1, "printf", buf);
	}
	
	// attempt to also record message remotely
	if ((type & PRINTF_MSG) && msgs_mc) {
		if (type & PRINTF_FF)
			send_encoded_msg_mc(msgs_mc, "MSG", "status_msg", "\f%s", buf);
		else
			send_encoded_msg_mc(msgs_mc, "MSG", "status_msg", "%s", buf);
	}
	
	if (buf) free(buf);
	buf = 0;
}
Example #5
0
static void update_task(void *param)
{
	conn_t *conn = (conn_t *) FROM_VOID_PARAM(param);
	bool force_check = (conn && conn->update_check == FORCE_CHECK);
	bool force_build = (conn && conn->update_check == FORCE_BUILD);
	bool ver_changed, update_install;
	
	lprintf("UPDATE: checking for updates\n");

	// Run curl in a Linux child process otherwise this thread will block and cause trouble
	// if the check is invoked from the admin page while there are active user connections.
	int status = child_task("kiwi.upd", POLL_MSEC(1000), curl_makefile_ctask, NULL);

	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
		lprintf("UPDATE: curl Makefile error, no Internet access? status=0x%08x WIFEXITED=%d WEXITSTATUS=%d\n",
		    status, WIFEXITED(status), WEXITSTATUS(status));
		if (force_check) report_result(conn);
		goto common_return;
	}
	
	FILE *fp;
	scallz("fopen Makefile.1", (fp = fopen("/root/" REPO_NAME "/Makefile.1", "r")));
		int n1, n2;
		n1 = fscanf(fp, "VERSION_MAJ = %d\n", &pending_maj);
		n2 = fscanf(fp, "VERSION_MIN = %d\n", &pending_min);
	fclose(fp);
	
	ver_changed = (n1 == 1 && n2 == 1 && (pending_maj > version_maj  || (pending_maj == version_maj && pending_min > version_min)));
	update_install = (admcfg_bool("update_install", NULL, CFG_REQUIRED) == true);
	
	if (force_check) {
		if (ver_changed)
			lprintf("UPDATE: version changed (current %d.%d, new %d.%d), but check only\n",
				version_maj, version_min, pending_maj, pending_min);
		else
			lprintf("UPDATE: running most current version\n");
		
		report_result(conn);
		goto common_return;
	} else

	if (ver_changed && !update_install && !force_build) {
		lprintf("UPDATE: version changed (current %d.%d, new %d.%d), but update install not enabled\n",
			version_maj, version_min, pending_maj, pending_min);
	} else
	
	if (ver_changed || force_build) {
		lprintf("UPDATE: version changed%s, current %d.%d, new %d.%d\n",
			force_build? " (forced)":"",
			version_maj, version_min, pending_maj, pending_min);
		lprintf("UPDATE: building new version..\n");
		update_in_progress = true;
        rx_server_user_kick(-1);        // kick everyone off to speed up build
        sleep(5);

		// Run build in a Linux child process so the server can continue to respond to connection requests
		// and display a "software update in progress" message.
		// This is because the calls to system() in update_build_ctask() block for the duration of the build.
		u4_t build_time = timer_sec();
		status = child_task("kiwi.bld", POLL_MSEC(1000), update_build_ctask, TO_VOID_PARAM(force_build));
		
        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
            lprintf("UPDATE: build error, no Internet access? status=0x%08x WIFEXITED=%d WEXITSTATUS=%d\n",
                status, WIFEXITED(status), WEXITSTATUS(status));
		    goto common_return;
		}
		
		lprintf("UPDATE: build took %d secs\n", timer_sec() - build_time);
		lprintf("UPDATE: switching to new version %d.%d\n", pending_maj, pending_min);
		if (admcfg_int("update_restart", NULL, CFG_REQUIRED) == 0) {
		    xit(0);
		} else {
		    lprintf("UPDATE: rebooting Beagle..\n");
		    system("sleep 3; reboot");
		}
	} else {
		lprintf("UPDATE: version %d.%d is current\n", version_maj, version_min);
	}
	
	if (daily_restart) {
	    lprintf("UPDATE: daily restart..\n");
	    xit(0);
	}

common_return:
	if (conn) conn->update_check = WAIT_UNTIL_NO_USERS;     // restore default
	update_pending = update_task_running = update_in_progress = false;
}