pax_global_header00006660000000000000000000000064142005313670014513gustar00rootroot0000000000000052 comment=9d78fc0c6143c4d1b7198c57be72a6699ce764c4 pd-mapper-1.0/000077500000000000000000000000001420053136700132405ustar00rootroot00000000000000pd-mapper-1.0/Android.bp000066400000000000000000000002121420053136700151360ustar00rootroot00000000000000cc_binary { name: "pd-mapper", vendor: true, srcs: [ "pd-mapper.c", "servreg_loc.c", ], shared_libs: ["libqrtr"], } pd-mapper-1.0/LICENSE000066400000000000000000000061241420053136700142500ustar00rootroot00000000000000/* * Copyright (c) 2018, Linaro Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 2016, Bjorn Andersson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ pd-mapper-1.0/Makefile000066400000000000000000000011631420053136700147010ustar00rootroot00000000000000PD_MAPPER := pd-mapper CFLAGS := -Wall -g -O2 LDFLAGS := -lqrtr prefix ?= /usr/local bindir := $(prefix)/bin servicedir := $(prefix)/lib/systemd/system SRCS := pd-mapper.c \ assoc.c \ json.c \ servreg_loc.c OBJS := $(SRCS:.c=.o) $(PD_MAPPER): $(OBJS) $(CC) -o $@ $^ $(LDFLAGS) pd-mapper.service: pd-mapper.service.in @sed 's+PD_MAPPER_PATH+$(bindir)+g' $< > $@ install: $(PD_MAPPER) pd-mapper.service @install -D -m 755 $(PD_MAPPER) $(DESTDIR)$(bindir)/$(PD_MAPPER) @install -D -m 644 pd-mapper.service $(DESTDIR)$(servicedir)/pd-mapper.service clean: rm -f $(PD_MAPPER) $(OBJS) pd-mapper.service pd-mapper-1.0/assoc.c000066400000000000000000000075641420053136700145300ustar00rootroot00000000000000/* * Copyright (c) 2013, Bjorn Andersson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "assoc.h" static unsigned long assoc_hash(const char *value) { unsigned long hash = 0; unsigned long g; const char *v = value; while (*v) { hash = (hash << 4) + *(v++); g = hash & 0xF0000000L; if (g) hash ^= g >> 24; hash &= ~g; } return hash; } void assoc_init(struct assoc *assoc, unsigned long size) { assert(size > 0); assoc->size = size; assoc->fill = 0; assoc->keys = calloc(size, sizeof(const char *)); assoc->values = malloc(size * sizeof(void *)); } void *assoc_get(struct assoc *assoc, const char *key) { unsigned long hash; hash = assoc_hash(key) % assoc->size; while (assoc->keys[hash]) { if (!strcmp(assoc->keys[hash], key)) return assoc->values[hash]; hash = (hash + 1) % assoc->size; } return NULL; } static void _assoc_set(struct assoc *assoc, const char *key, void *value) { struct assoc new_set; unsigned long hash; unsigned long i; assert(assoc->fill < assoc->size); /* Grow set at 80% utilization */ if (5 * assoc->fill > 4 * assoc->size) { assoc_init(&new_set, assoc->size * 5 / 4); for (i = 0; i < assoc->size; i++) if (assoc->keys[i]) assoc_set(&new_set, assoc->keys[i], assoc->values[i]); free(assoc->keys); free(assoc->values); assoc->keys = new_set.keys; assoc->values = new_set.values; assoc->fill = new_set.fill; assoc->size = new_set.size; } hash = assoc_hash(key) % assoc->size; while (assoc->keys[hash]) { if (!strcmp(assoc->keys[hash], key)) { assoc->values[hash] = value; return; } hash = (hash + 1) % assoc->size; } assoc->keys[hash] = key; assoc->values[hash] = value; assoc->fill++; } void assoc_set(struct assoc *assoc, const char *key, void *value) { _assoc_set(assoc, strdup(key), value); } const char *assoc_next(struct assoc *assoc, void **value, unsigned long *iter) { unsigned long it = *iter; while (it < assoc->size && !assoc->keys[it]) it++; if (it == assoc->size) return NULL; *iter = it + 1; if (it < assoc->size) { if (value) *value = assoc->values[it]; return assoc->keys[it]; } else { return NULL; } } void assoc_destroy(struct assoc *assoc) { unsigned long i; for (i = 0; i < assoc->size; i++) free((void*)assoc->keys[i]); free(assoc->keys); free(assoc->values); assoc->size = 0; } pd-mapper-1.0/assoc.h000066400000000000000000000042561420053136700145300ustar00rootroot00000000000000/* * Copyright (c) 2013, Bjorn Andersson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ASSOC_H__ #define __ASSOC_H__ struct assoc { unsigned long size; unsigned long fill; const char **keys; void **values; }; void assoc_init(struct assoc *assoc, unsigned long size); void *assoc_get(struct assoc *assoc, const char *key); void assoc_set(struct assoc *assoc, const char *key, void *value); const char *assoc_next(struct assoc *assoc, void **value, unsigned long *iter); void assoc_destroy(struct assoc *assoc); #define assoc_foreach(key, value, assoc, iter) \ for ((iter) = 0, (key) = assoc_next((assoc), (value), &(iter)); \ (key); \ (key) = assoc_next((assoc), (value), &(iter))) #endif pd-mapper-1.0/json.c000066400000000000000000000176631420053136700143720ustar00rootroot00000000000000/* * Copyright (c) 2018-2019, Linaro Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include "json.h" static const char *input_buf; static int input_pos; static int input_len; static int json_parse_array(struct json_value *array); static int json_parse_object(struct json_value *object); static int json_parse_property(struct json_value *value); static int input(void) { if (input_pos >= input_len) return 0; return input_buf[input_pos++]; } static void unput(void) { input_pos--; } static void json_skip_whitespace(void) { int ch; while ((ch = input()) && isspace(ch)) ; unput(); } static int json_parse_string(struct json_value *value) { char buf[128]; char *b = buf; int ch; ch = input(); if (ch != '"') { unput(); return 0; } while ((ch = input()) && ch != '"' && b - buf < sizeof(buf) - 1) *b++ = ch; *b = '\0'; if (!ch) return -1; value->type = JSON_TYPE_STRING; value->u.string = strdup(buf); return 1; } static int json_parse_number(struct json_value *value) { char buf[20]; char *b = buf; int ch; while ((ch = input()) && isdigit(ch) && b - buf < sizeof(buf) - 1) *b++ = ch; *b = '\0'; unput(); if (b == buf) return 0; value->type = JSON_TYPE_NUMBER; value->u.number = strtod(buf, NULL); return 1; } static int json_parse_keyword(struct json_value *value) { const char *match; const char *m; int ch; ch = input(); switch (ch) { case 't': match = "true"; value->type = JSON_TYPE_TRUE; break; case 'f': match = "false"; value->type = JSON_TYPE_FALSE; break; case 'n': match = "null"; value->type = JSON_TYPE_NULL; break; default: unput(); return 0; } m = match; while (*m && *m++ == ch) ch = input(); unput(); return *m == '\0' ? 1 : -1; } static int json_parse_value(struct json_value *value) { int ret; json_skip_whitespace(); ret = json_parse_object(value); if (ret) goto out; ret = json_parse_array(value); if (ret) goto out; ret = json_parse_string(value); if (ret) goto out; ret = json_parse_number(value); if (ret) goto out; ret = json_parse_keyword(value); if (ret) goto out; fprintf(stderr, "unable to match a value\n"); return -1; out: json_skip_whitespace(); return ret; } static int json_parse_array(struct json_value *array) { struct json_value *value; struct json_value *last = NULL; int ret; int ch; ch = input(); if (ch != '[') { unput(); return 0; } array->type = JSON_TYPE_ARRAY; do { value = calloc(1, sizeof(*value)); if (!value) return -1; ret = json_parse_value(value); if (ret <= 0) { free(value); return -1; } if (!array->u.value) array->u.value = value; if (last) last->next = value; last = value; ch = input(); if (ch == ']') { return 1; } } while (ch == ','); fprintf(stderr, "expected ',' got '%c'\n", ch); return -1; } static int json_parse_object(struct json_value *object) { struct json_value *value; struct json_value *last = NULL; int ret; int ch; ch = input(); if (ch != '{') { unput(); return 0; } object->type = JSON_TYPE_OBJECT; do { value = calloc(1, sizeof(*value)); if (!value) return -1; ret = json_parse_property(value); if (ret <= 0) { free(value); return -1; } if (!object->u.value) object->u.value = value; if (last) last->next = value; last = value; ch = input(); if (ch == '}') { return 1; } } while (ch == ','); return -1; } static int json_parse_property(struct json_value *value) { struct json_value key; int ret; int ch; json_skip_whitespace(); ret = json_parse_string(&key); if (ret <= 0) return -1; value->key = key.u.string; json_skip_whitespace(); ch = input(); if (ch != ':') return -1; ret = json_parse_value(value); if (ret <= 0) return -1; return 1; } struct json_value *json_parse(const char *json) { struct json_value *root; int ret; input_buf = json; input_pos = 0; input_len = strlen(input_buf); root = calloc(1, sizeof(*root)); if (!root) return NULL; ret = json_parse_value(root); if (ret != 1) { free(root); return NULL; } return root; } struct json_value *json_parse_file(const char *file) { struct json_value *root; struct stat sb; int ret; int fd; fd = open(file, O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open %s: %s\n", file, strerror(errno)); return NULL; } ret = fstat(fd, &sb); if (ret < 0) return NULL; input_pos = 0; input_len = sb.st_size; input_buf = malloc(sb.st_size); ret = read(fd, (char *)input_buf, input_len); close(fd); if (ret != input_len) { fprintf(stderr, "failed to read %d bytes form %s\n", input_len, file); return NULL; } root = calloc(1, sizeof(*root)); if (!root) return NULL; ret = json_parse_value(root); if (ret != 1) { json_free(root); return NULL; } return root; } struct json_value *json_get_child(struct json_value *object, const char *key) { struct json_value *it; if(object->type != JSON_TYPE_OBJECT) return NULL; for (it = object->u.value; it; it = it->next) { if (!strcmp(it->key, key)) return it; } return NULL; } int json_count_children(struct json_value *array) { struct json_value *it; int count = 0; if (!array || array->type != JSON_TYPE_ARRAY) return -1; for (it = array->u.value; it; it = it->next) count++; return count; } int json_get_number(struct json_value *object, const char *key, double *number) { struct json_value *it; if (!object || object->type != JSON_TYPE_OBJECT) return -1; for (it = object->u.value; it; it = it->next) { if (!strcmp(it->key, key)) { if (it->type != JSON_TYPE_NUMBER) return -1; *number = it->u.number; return 0; } } return -1; } const char *json_get_string(struct json_value *object, const char *key) { struct json_value *it; if (!object || object->type != JSON_TYPE_OBJECT) return NULL; for (it = object->u.value; it; it = it->next) { if (!strcmp(it->key, key)) { if (it->type != JSON_TYPE_STRING) return NULL; return it->u.string; } } return NULL; } void json_free(struct json_value *value) { struct json_value *next; struct json_value *it; free((char *)value->key); switch (value->type) { case JSON_TYPE_OBJECT: case JSON_TYPE_ARRAY: it = value->u.value; while (it) { next = it->next; json_free(it); it = next; } break; case JSON_TYPE_STRING: free((char *)value->u.string); break; } free(value); } pd-mapper-1.0/json.h000066400000000000000000000044761420053136700143750ustar00rootroot00000000000000/* * Copyright (c) 2019, Linaro Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __JSON_H__ #define __JSON_H__ enum { JSON_TYPE_UNKNOWN, JSON_TYPE_TRUE, JSON_TYPE_FALSE, JSON_TYPE_NULL, JSON_TYPE_NUMBER, JSON_TYPE_STRING, JSON_TYPE_ARRAY, JSON_TYPE_OBJECT, }; struct json_value { const char *key; int type; union { double number; const char *string; struct json_value *value; } u; struct json_value *next; }; struct json_value *json_parse(const char *json); struct json_value *json_parse_file(const char *file); int json_count_children(struct json_value *array); struct json_value *json_get_child(struct json_value *object, const char *key); int json_get_number(struct json_value *object, const char *key, double *number); const char *json_get_string(struct json_value *object, const char *key); void json_free(struct json_value *value); #endif pd-mapper-1.0/pd-mapper.c000066400000000000000000000215271420053136700153000ustar00rootroot00000000000000/* * Copyright (c) 2018, Linaro Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "assoc.h" #include "json.h" #include "servreg_loc.h" struct pd_map { const char *service; const char *domain; int instance; }; static struct pd_map *pd_maps; static void handle_get_domain_list(int sock, const struct qrtr_packet *pkt) { struct servreg_loc_get_domain_list_resp resp = {}; struct servreg_loc_get_domain_list_req req = {}; struct servreg_loc_domain_list_entry *entry; DEFINE_QRTR_PACKET(resp_buf, 256); const struct pd_map *pd_map = pd_maps; unsigned int txn; ssize_t len; int ret; ret = qmi_decode_message(&req, &txn, pkt, QMI_REQUEST, SERVREG_LOC_GET_DOMAIN_LIST, servreg_loc_get_domain_list_req_ei); if (ret < 0) { resp.result.result = QMI_RESULT_FAILURE; resp.result.error = QMI_ERR_MALFORMED_MSG; goto respond; } req.name[sizeof(req.name)-1] = '\0'; resp.result.result = QMI_RESULT_SUCCESS; resp.db_revision_valid = 1; resp.db_revision = 1; while (pd_map->service) { if (!strcmp(pd_map->service, req.name)) { entry = &resp.domain_list[resp.domain_list_len++]; strcpy(entry->name, pd_map->domain); entry->name_len = strlen(pd_map->domain); entry->instance_id = pd_map->instance; } pd_map++; } if (resp.domain_list_len) resp.domain_list_valid = 1; resp.total_domains_valid = 1; resp.total_domains = resp.domain_list_len; respond: len = qmi_encode_message(&resp_buf, QMI_RESPONSE, SERVREG_LOC_GET_DOMAIN_LIST, txn, &resp, servreg_loc_get_domain_list_resp_ei); if (len < 0) { fprintf(stderr, "[PD-MAPPER] failed to encode get_domain_list response: %s\n", strerror(-len)); return; } ret = qrtr_sendto(sock, pkt->node, pkt->port, resp_buf.data, resp_buf.data_len); if (ret < 0) { fprintf(stderr, "[PD-MAPPER] failed to send get_domain_list response: %s\n", strerror(-ret)); } } static int pd_load_map(const char *file) { static int num_pd_maps; struct json_value *sr_service; struct json_value *sr_domain; struct json_value *root; struct json_value *it; const char *subdomain; const char *provider; const char *service; const char *domain; const char *soc; struct pd_map *newp; struct pd_map *map; double number; int count; int ret; root = json_parse_file(file); if (!root) return -1; sr_domain = json_get_child(root, "sr_domain"); soc = json_get_string(sr_domain, "soc"); domain = json_get_string(sr_domain, "domain"); subdomain = json_get_string(sr_domain, "subdomain"); ret = json_get_number(sr_domain, "qmi_instance_id", &number); if (ret) return ret; if (!soc || !domain || !subdomain) { fprintf(stderr, "failed to parse sr_domain\n"); return -1; } sr_service = json_get_child(root, "sr_service"); count = json_count_children(sr_service); if (count < 0) return count; newp = realloc(pd_maps, (num_pd_maps + count + 1) * sizeof(*newp)); if (!newp) return -1; pd_maps = newp; for (it = sr_service->u.value; it; it = it->next) { provider = json_get_string(it, "provider"); service = json_get_string(it, "service"); if (!provider || !service) { fprintf(stderr, "failed to parse provdider or service from %s\n", file); return -1; } map = &pd_maps[num_pd_maps++]; map->service = malloc(strlen(provider) + strlen(service) + 2); sprintf((char *)map->service, "%s/%s", provider, service); map->domain = malloc(strlen(soc) + strlen(domain) + strlen(subdomain) + 3); sprintf((char *)map->domain, "%s/%s/%s", soc, domain, subdomain); map->instance = number; } pd_maps[num_pd_maps].service = NULL; json_free(root); return 0; } #define FIRMWARE_BASE "/lib/firmware/" static int pd_enumerate_jsons(struct assoc *json_set) { char firmware_value[PATH_MAX]; char json_path[PATH_MAX]; char firmware_attr[32]; struct dirent *fw_de; char path[PATH_MAX]; struct dirent *de; int firmware_fd; DIR *class_dir; int class_fd; DIR *fw_dir; size_t len; size_t n; class_fd = open("/sys/class/remoteproc", O_RDONLY | O_DIRECTORY); if (class_fd < 0) { warn("failed to open remoteproc class"); return -1; } class_dir = fdopendir(class_fd); if (!class_dir) { warn("failed to opendir"); goto close_class; } while ((de = readdir(class_dir)) != NULL) { if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; if (strlen(de->d_name) + sizeof("/firmware") > sizeof(firmware_attr)) continue; strcpy(firmware_attr, de->d_name); strcat(firmware_attr, "/firmware"); firmware_fd = openat(class_fd, firmware_attr, O_RDONLY); if (firmware_fd < 0) continue; n = read(firmware_fd, firmware_value, sizeof(firmware_value)); close(firmware_fd); if (n < 0) { continue; } firmware_value[n] = '\0'; if (strlen(FIRMWARE_BASE) + strlen(firmware_value) + 1 > sizeof(path)) continue; strcpy(path, FIRMWARE_BASE); strcat(path, dirname(firmware_value)); fw_dir = opendir(path); while ((fw_de = readdir(fw_dir)) != NULL) { if (!strcmp(fw_de->d_name, ".") || !strcmp(fw_de->d_name, "..")) continue; len = strlen(fw_de->d_name); if (len < 5 || strcmp(&fw_de->d_name[len - 4], ".jsn")) continue; if (strlen(FIRMWARE_BASE) + strlen(firmware_value) + 1 + strlen(fw_de->d_name) + 1 > sizeof(path)) continue; strcpy(json_path, path); strcat(json_path, "/"); strcat(json_path, fw_de->d_name); assoc_set(json_set, json_path, NULL); } closedir(fw_dir); } closedir(class_dir); close_class: close(class_fd); return 0; } static int pd_load_maps(void) { struct assoc json_set; unsigned long it; const char *jsn; int ret = 0; assoc_init(&json_set, 20); pd_enumerate_jsons(&json_set); assoc_foreach(jsn, NULL, &json_set, it) { ret = pd_load_map(jsn); if (ret < 0) break; } assoc_destroy(&json_set); return ret; } int main(int argc, char **argv) { struct sockaddr_qrtr sq; struct qrtr_packet pkt; unsigned int msg_id; socklen_t sl; char buf[4096]; int ret; int fd; ret = pd_load_maps(); if (ret) exit(1); if (!pd_maps) { fprintf(stderr, "no pd maps available\n"); exit(1); } fd = qrtr_open(0); if (fd < 0) { fprintf(stderr, "failed to open qrtr socket\n"); exit(1); } ret = qrtr_publish(fd, SERVREG_QMI_SERVICE, SERVREG_QMI_VERSION, SERVREG_QMI_INSTANCE); if (ret < 0) { fprintf(stderr, "failed to publish service registry service\n"); exit(1); } for (;;) { ret = qrtr_poll(fd, -1); if (ret < 0) { if (errno == EINTR) { continue; } else { fprintf(stderr, "qrtr_poll failed\n"); break; } } sl = sizeof(sq); ret = recvfrom(fd, buf, sizeof(buf), 0, (void *)&sq, &sl); if (ret < 0) { ret = -errno; if (ret != -ENETRESET) fprintf(stderr, "[PD-MAPPER] recvfrom failed: %d\n", ret); return ret; } ret = qrtr_decode(&pkt, buf, ret, &sq); if (ret < 0) { fprintf(stderr, "[PD-MAPPER] unable to decode qrtr packet\n"); return ret; } switch (pkt.type) { case QRTR_TYPE_DATA: ret = qmi_decode_header(&pkt, &msg_id); if (ret < 0) continue; switch (msg_id) { case SERVREG_LOC_GET_DOMAIN_LIST: handle_get_domain_list(fd, &pkt); break; case SERVREG_LOC_PFR: printf("[PD-MAPPER] pfr\n"); break; }; break; }; } close(fd); return 0; } pd-mapper-1.0/pd-mapper.service.in000066400000000000000000000003001420053136700171050ustar00rootroot00000000000000[Unit] Description=Qualcomm PD mapper service Requires=qrtr-ns.service After=qrtr-ns.service [Service] ExecStart=PD_MAPPER_PATH/pd-mapper Restart=always [Install] WantedBy=multi-user.target pd-mapper-1.0/servreg_loc.c000066400000000000000000000101361420053136700157170ustar00rootroot00000000000000#include #include #include "servreg_loc.h" struct qmi_elem_info servreg_loc_qmi_result_ei[] = { { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, .elem_size = sizeof(uint16_t), .offset = offsetof(struct servreg_loc_qmi_result, result), }, { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, .elem_size = sizeof(uint16_t), .offset = offsetof(struct servreg_loc_qmi_result, error), }, {} }; struct qmi_elem_info servreg_loc_domain_list_entry_ei[] = { { .data_type = QMI_STRING, .elem_len = 256, .elem_size = sizeof(char), .offset = offsetof(struct servreg_loc_domain_list_entry, name) }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .offset = offsetof(struct servreg_loc_domain_list_entry, instance_id), }, { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, .elem_size = sizeof(uint8_t), .offset = offsetof(struct servreg_loc_domain_list_entry, service_data_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .offset = offsetof(struct servreg_loc_domain_list_entry, service_data), }, {} }; struct qmi_elem_info servreg_loc_get_domain_list_req_ei[] = { { .data_type = QMI_STRING, .elem_len = 256, .elem_size = sizeof(char), .array_type = VAR_LEN_ARRAY, .tlv_type = 1, .offset = offsetof(struct servreg_loc_get_domain_list_req, name) }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(bool), .tlv_type = 16, .offset = offsetof(struct servreg_loc_get_domain_list_req, offset_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .tlv_type = 16, .offset = offsetof(struct servreg_loc_get_domain_list_req, offset), }, {} }; struct qmi_elem_info servreg_loc_get_domain_list_resp_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, .elem_size = sizeof(struct servreg_loc_qmi_result), .tlv_type = 2, .offset = offsetof(struct servreg_loc_get_domain_list_resp, result), .ei_array = servreg_loc_qmi_result_ei, }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(bool), .tlv_type = 16, .offset = offsetof(struct servreg_loc_get_domain_list_resp, total_domains_valid), }, { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, .elem_size = sizeof(uint16_t), .tlv_type = 16, .offset = offsetof(struct servreg_loc_get_domain_list_resp, total_domains), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(bool), .tlv_type = 17, .offset = offsetof(struct servreg_loc_get_domain_list_resp, db_revision_valid), }, { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, .elem_size = sizeof(uint16_t), .tlv_type = 17, .offset = offsetof(struct servreg_loc_get_domain_list_resp, db_revision), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(bool), .tlv_type = 18, .offset = offsetof(struct servreg_loc_get_domain_list_resp, domain_list_valid), }, { .data_type = QMI_DATA_LEN, .elem_len = 1, .elem_size = sizeof(uint8_t), .tlv_type = 18, .offset = offsetof(struct servreg_loc_get_domain_list_resp, domain_list_len), }, { .data_type = QMI_STRUCT, .elem_len = 255, .elem_size = sizeof(struct servreg_loc_domain_list_entry), .array_type = VAR_LEN_ARRAY, .tlv_type = 18, .offset = offsetof(struct servreg_loc_get_domain_list_resp, domain_list), .ei_array = servreg_loc_domain_list_entry_ei, }, {} }; struct qmi_elem_info servreg_loc_pfr_req_ei[] = { { .data_type = QMI_STRING, .elem_len = 256, .elem_size = sizeof(char), .array_type = VAR_LEN_ARRAY, .tlv_type = 1, .offset = offsetof(struct servreg_loc_pfr_req, service) }, { .data_type = QMI_STRING, .elem_len = 256, .elem_size = sizeof(char), .array_type = VAR_LEN_ARRAY, .tlv_type = 2, .offset = offsetof(struct servreg_loc_pfr_req, reason) }, {} }; struct qmi_elem_info servreg_loc_pfr_resp_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, .elem_size = sizeof(struct servreg_loc_qmi_result), .tlv_type = 2, .offset = offsetof(struct servreg_loc_pfr_resp, result), .ei_array = servreg_loc_qmi_result_ei, }, {} }; pd-mapper-1.0/servreg_loc.h000066400000000000000000000027421420053136700157300ustar00rootroot00000000000000#ifndef __QMI_SERVREG_LOC_H__ #define __QMI_SERVREG_LOC_H__ #include #include #include "libqrtr.h" #define SERVREG_QMI_SERVICE 64 #define SERVREG_QMI_VERSION 257 #define SERVREG_QMI_INSTANCE 0 #define QMI_RESULT_SUCCESS 0 #define QMI_RESULT_FAILURE 1 #define QMI_ERR_NONE 0 #define QMI_ERR_INTERNAL 1 #define QMI_ERR_MALFORMED_MSG 2 #define SERVREG_LOC_GET_DOMAIN_LIST 33 #define SERVREG_LOC_PFR 36 struct servreg_loc_qmi_result { uint16_t result; uint16_t error; }; struct servreg_loc_domain_list_entry { uint32_t name_len; char name[256]; uint32_t instance_id; uint8_t service_data_valid; uint32_t service_data; }; struct servreg_loc_get_domain_list_req { uint32_t name_len; char name[256]; bool offset_valid; uint32_t offset; }; struct servreg_loc_get_domain_list_resp { struct servreg_loc_qmi_result result; bool total_domains_valid; uint16_t total_domains; bool db_revision_valid; uint16_t db_revision; bool domain_list_valid; uint32_t domain_list_len; struct servreg_loc_domain_list_entry domain_list[255]; }; struct servreg_loc_pfr_req { uint32_t service_len; char service[256]; uint32_t reason_len; char reason[256]; }; struct servreg_loc_pfr_resp { struct servreg_loc_qmi_result result; }; extern struct qmi_elem_info servreg_loc_get_domain_list_req_ei[]; extern struct qmi_elem_info servreg_loc_get_domain_list_resp_ei[]; extern struct qmi_elem_info servreg_loc_pfr_req_ei[]; extern struct qmi_elem_info servreg_loc_pfr_resp_ei[]; #endif pd-mapper-1.0/servreg_loc.qmi000066400000000000000000000016641420053136700162710ustar00rootroot00000000000000package servreg_loc; const SERVREG_QMI_SERVICE = 0x40; const SERVREG_QMI_VERSION = 0x101; const SERVREG_QMI_INSTANCE = 0x0; const QMI_RESULT_SUCCESS = 0; const QMI_RESULT_FAILURE = 1; const QMI_ERR_NONE = 0; const QMI_ERR_INTERNAL = 1; const QMI_ERR_MALFORMED_MSG = 2; const SERVREG_LOC_GET_DOMAIN_LIST = 0x21; const SERVREG_LOC_PFR = 0x24; struct qmi_result { u16 result; u16 error; }; struct domain_list_entry { string name; u32 instance_id; u8 service_data_valid; u32 service_data; }; request get_domain_list_req { required string name = 1; optional u32 offset = 0x10; } = 0x20; response get_domain_list_resp { required qmi_result result = 2; optional u16 total_domains = 0x10; optional u16 db_revision = 0x11; optional domain_list_entry domain_list[255] = 0x12; } = 0x20; request pfr_req { required string service = 1; required string reason = 2; } = 0x24; response pfr_resp { required qmi_result result = 2; } = 0x24;