db845c: qcom: Add userspace tools to talk to dsp and modem

Add Qcom userspace tools and their respective sepolicy rules.

Userspace tools are downloaded from following github:

To trigger loading of wlan firmware on SDM845
git clone https://github.com/andersson/pd-mapper

Userspace reference for net/qrtr in the Linux kernel
git clone https://github.com/andersson/qrtr

Qualcomm Remote Filesystem Service Implementation
git clone https://github.com/andersson/rmtfs

Trivial File Transfer Protocol server over AF_QIPCRTR
git clone https://github.com/andersson/tqftpserv

Change-Id: Ic466af6fef010a9b71c90e38205f49a876b001e2
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
diff --git a/qcom/qrtr/src/lookup.c b/qcom/qrtr/src/lookup.c
new file mode 100644
index 0000000..3312e40
--- /dev/null
+++ b/qcom/qrtr/src/lookup.c
@@ -0,0 +1,237 @@
+#include <err.h>
+#include <errno.h>
+#include <libgen.h>
+#include <linux/qrtr.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "libqrtr.h"
+#include "logging.h"
+#include "ns.h"
+#include "util.h"
+
+#define DIAG_SERVICE 4097
+
+static const struct {
+	unsigned int service;
+	unsigned int ifilter;
+	const char *name;
+} common_names[] = {
+	{ 0, 0, "Control service" },
+	{ 1, 0, "Wireless Data Service" },
+	{ 2, 0, "Device Management Service" },
+	{ 3, 0, "Network Access Service" },
+	{ 4, 0, "Quality Of Service service" },
+	{ 5, 0, "Wireless Messaging Service" },
+	{ 6, 0, "Position Determination Service" },
+	{ 7, 0, "Authentication service" },
+	{ 8, 0, "AT service" },
+	{ 9, 0, "Voice service" },
+	{ 10, 0, "Card Application Toolkit service (v2)" },
+	{ 11, 0, "User Identity Module service" },
+	{ 12, 0, "Phonebook Management service" },
+	{ 13, 0, "QCHAT service" },
+	{ 14, 0, "Remote file system service" },
+	{ 15, 0, "Test service" },
+	{ 16, 0, "Location service (~ PDS v2)" },
+	{ 17, 0, "Specific absorption rate service" },
+	{ 18, 0, "IMS settings service" },
+	{ 19, 0, "Analog to digital converter driver service" },
+	{ 20, 0, "Core sound driver service" },
+	{ 21, 0, "Modem embedded file system service" },
+	{ 22, 0, "Time service" },
+	{ 23, 0, "Thermal sensors service" },
+	{ 24, 0, "Thermal mitigation device service" },
+	{ 25, 0, "Service access proxy service" },
+	{ 26, 0, "Wireless data administrative service" },
+	{ 27, 0, "TSYNC control service" },
+	{ 28, 0, "Remote file system access service" },
+	{ 29, 0, "Circuit switched videotelephony service" },
+	{ 30, 0, "Qualcomm mobile access point service" },
+	{ 31, 0, "IMS presence service" },
+	{ 32, 0, "IMS videotelephony service" },
+	{ 33, 0, "IMS application service" },
+	{ 34, 0, "Coexistence service" },
+	{ 36, 0, "Persistent device configuration service" },
+	{ 38, 0, "Simultaneous transmit service" },
+	{ 39, 0, "Bearer independent transport service" },
+	{ 40, 0, "IMS RTP service" },
+	{ 41, 0, "RF radiated performance enhancement service" },
+	{ 42, 0, "Data system determination service" },
+	{ 43, 0, "Subsystem control service" },
+	{ 49, 0, "IPA control service" },
+	{ 51, 0, "CoreSight remote tracing service" },
+	{ 52, 0, "Dynamic Heap Memory Sharing" },
+	{ 64, 0, "Service registry locator service" },
+	{ 66, 0, "Service registry notification service" },
+	{ 69, 0, "ATH10k WLAN firmware service" },
+	{ 224, 0, "Card Application Toolkit service (v1)" },
+	{ 225, 0, "Remote Management Service" },
+	{ 226, 0, "Open Mobile Alliance device management service" },
+	{ 312, 0, "QBT1000 Ultrasonic Fingerprint Sensor service" },
+	{ 769, 0, "SLIMbus control service" },
+	{ 771, 0, "Peripheral Access Control Manager service" },
+	{ DIAG_SERVICE, 0, "DIAG service" },
+};
+
+static const char *diag_instance_base_str(unsigned int instance_base)
+{
+	switch (instance_base) {
+		case 0: return "MODEM";
+		case 1: return "LPASS";
+		case 2: return "WCNSS";
+		case 3: return "SENSORS";
+		case 4: return "CDSP";
+		case 5: return "WDSP";
+		default: return "<unk>";
+	}
+}
+
+static const char *diag_instance_str(unsigned int instance)
+{
+	switch (instance) {
+		case 0: return "CNTL";
+		case 1: return "CMD";
+		case 2: return "DATA";
+		case 3: return "DCI_CMD";
+		case 4: return "DCI";
+		default: return "<unk>";
+	}
+}
+
+static int get_diag_instance_info(char *str, size_t size, unsigned int instance)
+{
+	return snprintf(str, size, "%s:%s",
+			diag_instance_base_str(instance >> 6),
+			diag_instance_str(instance & 0x3f));
+}
+
+static unsigned int read_num_le(const char *str, int *rcp)
+{
+	unsigned int ret;
+	char *e;
+
+	if (*rcp)
+		return 0;
+
+	errno = 0;
+	ret = strtoul(str, &e, 0);
+	*rcp = -(errno || *e);
+
+	return cpu_to_le32(ret);
+}
+
+int main(int argc, char **argv)
+{
+	struct qrtr_ctrl_pkt pkt;
+	struct sockaddr_qrtr sq;
+	unsigned int instance;
+	unsigned int service;
+	unsigned int version;
+	unsigned int node;
+	unsigned int port;
+	socklen_t sl = sizeof(sq);
+	struct timeval tv;
+	int sock;
+	int len;
+	int rc;
+	const char *progname = basename(argv[0]);
+
+	qlog_setup(progname, false);
+
+	rc = 0;
+	memset(&pkt, 0, sizeof(pkt));
+
+	switch (argc) {
+	default:
+		rc = -1;
+		break;
+	case 3: pkt.server.instance = read_num_le(argv[2], &rc);
+	case 2: pkt.server.service = read_num_le(argv[1], &rc);
+	case 1: break;
+	}
+	if (rc) {
+		fprintf(stderr, "Usage: %s [<service> [<instance> [<filter>]]]\n", progname);
+		exit(1);
+	}
+
+	sock = socket(AF_QIPCRTR, SOCK_DGRAM, 0);
+	if (sock < 0)
+		PLOGE_AND_EXIT("sock(AF_QIPCRTR)");
+
+	rc = getsockname(sock, (void *)&sq, &sl);
+	if (rc || sq.sq_family != AF_QIPCRTR || sl != sizeof(sq))
+		PLOGE_AND_EXIT("getsockname()");
+
+	sq.sq_port = QRTR_PORT_CTRL;
+
+	tv.tv_sec = 1;
+	tv.tv_usec = 0;
+
+	pkt.cmd = cpu_to_le32(QRTR_TYPE_NEW_LOOKUP);
+
+	rc = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+	if (rc)
+		PLOGE_AND_EXIT("setsockopt(SO_RCVTIMEO)");
+
+	rc = sendto(sock, &pkt, sizeof(pkt), 0, (void *)&sq, sizeof(sq));
+	if (rc < 0)
+		PLOGE_AND_EXIT("sendto()");
+
+	printf("  Service Version Instance Node  Port\n");
+
+	while ((len = recv(sock, &pkt, sizeof(pkt), 0)) > 0) {
+		unsigned int type = le32_to_cpu(pkt.cmd);
+		const char *name = NULL;
+		unsigned int i;
+
+		if (len < sizeof(pkt) || type != QRTR_TYPE_NEW_SERVER) {
+			PLOGW("invalid/short packet");
+			continue;
+		}
+
+		if (!pkt.server.service && !pkt.server.instance &&
+		    !pkt.server.node && !pkt.server.port)
+			break;
+
+		service = le32_to_cpu(pkt.server.service);
+		version = le32_to_cpu(pkt.server.instance) & 0xff;
+		instance = le32_to_cpu(pkt.server.instance) >> 8;
+		node = le32_to_cpu(pkt.server.node);
+		port = le32_to_cpu(pkt.server.port);
+
+		for (i = 0; i < sizeof(common_names)/sizeof(common_names[0]); ++i) {
+			if (service != common_names[i].service)
+				continue;
+			if (instance &&
+			   (instance & common_names[i].ifilter) != common_names[i].ifilter)
+				continue;
+			name = common_names[i].name;
+		}
+		if (!name)
+			name = "<unknown>";
+
+		if (service == DIAG_SERVICE) {
+			char buf[24];
+			instance = le32_to_cpu(pkt.server.instance);
+			get_diag_instance_info(buf, sizeof(buf), instance);
+			printf("%9d %7s %8d %4d %5d %s (%s)\n",
+				service, "N/A", instance, node, port, name, buf);
+		} else {
+			printf("%9d %7d %8d %4d %5d %s\n",
+				service, version, instance, node, port, name);
+		}
+	}
+
+	if (len < 0)
+		PLOGE_AND_EXIT("recv()");
+
+	close(sock);
+
+	return 0;
+}