diff --git a/zte-mf823/Makefile b/zte-mf823/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3ce6719db2432ae40ecdb3fdc9a939bfc910866b --- /dev/null +++ b/zte-mf823/Makefile @@ -0,0 +1,36 @@ +CC = gcc +CFLAGS = -g -Wall +LIBS = -ljson-c -lubox -lubus -luci -lcurl + +PAOBJS = parse_args.o +PASRCS = parse_args.c +HSRCS = parse_args.h + +all: libmobile dongle_apn dongle_pin dongle_network + +libmobile: ${MOBJS} + ${CC} -c ${MSRCS} -o ${MOBJS} + +DAOBJS = dongle_apn.o +DASRCS = dongle_apn.c +dongle_apn: ${DAOBJS} + ${CC} ${CFLAGS} ${DAOBJS} ${MOBJS} -o dongle_apn ${LIBS} + +DPOBJS = dongle_pin.o +DPSRCS = dongle_pin.c +dongle_pin: ${DPOBJS} + ${CC} ${CFLAGS} ${DPOBJS} ${MOBJS} -o dongle_pin ${LIBS} + +DNOBJS = dongle_network.o +DNSRCS = dongle_network.c +dongle_network: ${DNOBJS} + ${CC} ${CFLAGS} ${DNOBJS} ${MOBJS} -o dongle_network ${LIBS} +clean: + rm -f dongle_apn dongle_pin dongle_network *.o + +codingstyle: + checkpatch.pl --no-tree -f *.c --terse + +cppcheck: + cppcheck --enable=all *.c + diff --git a/zte-mf823/common.h b/zte-mf823/common.h new file mode 100644 index 0000000000000000000000000000000000000000..cad2ff1dd5f4d85ad8ad0012a33c755e365bcbc7 --- /dev/null +++ b/zte-mf823/common.h @@ -0,0 +1,10 @@ +#ifndef COMMON_H +#define COMMON_H +#define PIPE_PATH "/tmp/appipe" +#define DEBUG(message, ...) \ + do \ + { \ + fprintf(stdout, "\n(DEBUG)\t"); \ + fprintf(stdout, message, ##__VA_ARGS__);\ + } while (0) +#endif diff --git a/zte-mf823/dongle_apn.c b/zte-mf823/dongle_apn.c new file mode 100644 index 0000000000000000000000000000000000000000..4bf679be5c686bec7f65da3f5c2f5e2a32d7c7f1 --- /dev/null +++ b/zte-mf823/dongle_apn.c @@ -0,0 +1,209 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <unistd.h> +#include <getopt.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <signal.h> +#include <time.h> +#include <limits.h> + +#include <libubox/list.h> +#include <libubus.h> + +#include "libmobile.h" + +struct ubus_context *ctx; + +enum { + APN, + __APN_MAX, +}; + +const struct blobmsg_policy apn_policy[__APN_MAX] = { + [APN] = {.name = "apn", .type = BLOBMSG_TYPE_STRING}, +}; + +int list_apn_profiles(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct json_object *apn_profiles = get_apn_profiles_json(); + struct blob_buf bb; + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + json_object_object_foreach(apn_profiles, key, val) { + char *apn_profile = json_object_get_string(val); + + if (strlen(apn_profile) > 0) { + char *apn_name = strtok(apn_profile, "($)"); + + blobmsg_add_string(&bb, key, apn_name); + } else + break; + } + ubus_send_reply(ctx, req, bb.head); + + json_object_put(apn_profiles); + blob_buf_free(&bb); + return 0; +} + +int delete_apn_profile(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct json_object *apn_profiles = get_apn_profiles_json(); + struct blob_attr *tb[__APN_MAX]; + char name[1024]; //what is max available name length in dongle? + int idx; + + blobmsg_parse(apn_policy, __APN_MAX, tb, blob_data(msg), blob_len(msg)); + name[0] = '\0'; + strncpy(name, (char *)blobmsg_data(tb[APN]), 1023); + printf("name to remove: %s\n", name); + + idx = get_apn_profile_idx(apn_profiles, name); + + if (idx >= 0) { + char response[1024]; + int rv; + + rv = _delete_apn(idx, response); + if (rv < 0) + return -1; + + struct json_object *parsed_response = json_tokener_parse(response); + struct blob_buf bb; + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + bb = json_to_blob(parsed_response, bb); + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + json_object_put(parsed_response); + json_object_put(apn_profiles); + } + + return 0; +} + +int set_apn_profile(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct json_object *apn_profiles = get_apn_profiles_json(); + struct blob_attr *tb[__APN_MAX]; + char apn[1024]; //STR_MAX or something from limits.h + int idx; + + blobmsg_parse(apn_policy, __APN_MAX, tb, blob_data(msg), blob_len(msg)); + + apn[0] = '\0'; + strncpy(apn, (char *)blobmsg_data(tb[APN]), 1023); + printf("apn %s\n", apn); + + idx = get_apn_profile_idx(apn_profiles, apn); + if (idx < 0) + goto fail; + + char *response = _set_apn_profile(idx); + + struct json_object *parsed_response = json_tokener_parse(response); + struct blob_buf bb; + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + bb = json_to_blob(parsed_response, bb); + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + json_object_put(parsed_response); +fail: + free(response); + json_object_put(apn_profiles); + return 0; +} + +int create_apn_profile(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__APN_MAX]; + char apn[1024]; //STR_MAX or something from limits.h + + blobmsg_parse(apn_policy, __APN_MAX, tb, blob_data(msg), blob_len(msg)); + + apn[0] = '\0'; + strncpy(apn, (char *)blobmsg_data(tb[APN]), 1023); + char *response = _create_apn_profile(apn); + struct json_object *parsed_response = json_tokener_parse(response); + struct blob_buf bb; + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + bb = json_to_blob(parsed_response, bb); + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + json_object_put(parsed_response); + free(response); + + return 0; +} + +int show_current_apn(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *wan_apn = get_current_wan_apn(); + struct json_object *parsed_response = json_tokener_parse(wan_apn); + struct blob_buf bb; + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + bb = json_to_blob(parsed_response, bb); + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + json_object_put(parsed_response); + free(wan_apn); + return 0; +} + +struct ubus_method dongle_object_methods[] = { + UBUS_METHOD_NOARG("list_apn_profiles", list_apn_profiles), + UBUS_METHOD("create_apn_profile", create_apn_profile, apn_policy), + UBUS_METHOD("delete_apn_profile", delete_apn_profile, apn_policy), + UBUS_METHOD("set_apn_profile", set_apn_profile, apn_policy), + UBUS_METHOD_NOARG("show_current_apn", show_current_apn), +}; + +struct ubus_object_type dongle_object_type = UBUS_OBJECT_TYPE("dongle", dongle_object_methods); + +struct ubus_object dongle_object = { + .name = "dongle.apn", + .type = &dongle_object_type, + .methods = dongle_object_methods, + .n_methods = ARRAY_SIZE(dongle_object_methods), +}; + +void init_ubus(void) +{ + ctx = ubus_connect(NULL); + if (!ctx) { + perror("ubus"); + exit(1); + } + ubus_add_uloop(ctx); +} + +int main(int argc, char **argv) +{ + uloop_init(); + init_ubus(); + ubus_add_object(ctx, &dongle_object); + uloop_run(); + + return 0; +} diff --git a/zte-mf823/dongle_network.c b/zte-mf823/dongle_network.c new file mode 100644 index 0000000000000000000000000000000000000000..81cb5af1b6b4f63151cb26186822177a8485aa58 --- /dev/null +++ b/zte-mf823/dongle_network.c @@ -0,0 +1,71 @@ +#include <ctype.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <unistd.h> +#include <getopt.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <signal.h> +#include <time.h> +#include <limits.h> + +#include <libubox/list.h> +#include <libubus.h> + +#include "libmobile.h" + +struct ubus_context *ctx; + +int signal_strength(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_buf bb; + + char * response = get_csv("rssi"); + struct json_object *parsed_response = json_tokener_parse(response); +print: + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + bb = json_to_blob(parsed_response, bb); + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + json_object_put(parsed_response); +fail: + return 0; +} + +struct ubus_method dongle_object_methods[] = { + UBUS_METHOD_NOARG("signal_strength", signal_strength), +}; + +struct ubus_object_type dongle_object_type = UBUS_OBJECT_TYPE("dongle", dongle_object_methods); + +struct ubus_object dongle_object = { + .name = "dongle.network", + .type = &dongle_object_type, + .methods = dongle_object_methods, + .n_methods = ARRAY_SIZE(dongle_object_methods), +}; + +void init_ubus(void) +{ + ctx = ubus_connect(NULL); + if (!ctx) { + perror("ubus"); + exit(1); + } + ubus_add_uloop(ctx); +} + +int main(int argc, char **argv) +{ + uloop_init(); + init_ubus(); + ubus_add_object(ctx, &dongle_object); + uloop_run(); + + return 0; +} diff --git a/zte-mf823/dongle_pin.c b/zte-mf823/dongle_pin.c new file mode 100644 index 0000000000000000000000000000000000000000..1f0ffdbb458e4873bec2cd779248ace5c4b8b4d0 --- /dev/null +++ b/zte-mf823/dongle_pin.c @@ -0,0 +1,293 @@ +#include <ctype.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <unistd.h> +#include <getopt.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <signal.h> +#include <time.h> +#include <limits.h> + +#include <libubox/list.h> +#include <libubus.h> + +#include "libmobile.h" + +struct ubus_context *ctx; + +enum { + NEW_PIN, + CURRENT_PIN, + __SET_PIN_MAX, +}; + +enum { + PIN, + __PIN_MAX, +}; + +const struct blobmsg_policy set_pin_policy[__SET_PIN_MAX] = { + [NEW_PIN] = {.name = "new_pin", .type = BLOBMSG_TYPE_STRING}, + [CURRENT_PIN] = {.name = "current_pin", .type = BLOBMSG_TYPE_STRING}, +}; + +const struct blobmsg_policy pin_policy[__PIN_MAX] = { + [PIN] = {.name = "pin", .type = BLOBMSG_TYPE_STRING}, +}; + +int print_response(struct json_object *parsed_response, ubus_context *ctx, ubus_request_data *req) +{ + struct blob_buf bb; + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + bb = json_to_blob(parsed_response, bb); + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + json_object_put(parsed_response); + return 0; +} + +int isdigits(const char *pin) +{ + while (*pin){ + if (isdigit(*pin++) == 0) + return false; + } + return true; +} + +int validate_pin_format(char *pin) +{ + if (!isdigits(pin)) { + printf("Please enter digits only!\n"); + goto fail; + } else if (strlen(pin) > 8 && strlen(pin) < 4 ) { + printf("Please enter between 4 to 8 digits!\n"); + goto fail; + } else if (atoi(pin) == 0) { + printf("0000 is not a valid pin! Lowest available is 0001\n"); + goto fail; + } + return 0; +fail: + return -1; +} + +int set_pin(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_buf bb; + struct blob_attr *tb[__SET_PIN_MAX]; + char new_pin[10] = {0}, current_pin[10] = {0}; + + blobmsg_parse(set_pin_policy, __SET_PIN_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[NEW_PIN] && !tb[CURRENT_PIN]) { + printf("Please enter both a new pin and old pin!"); + goto fail; + } + + strncpy(new_pin, (char *)blobmsg_data(tb[NEW_PIN]), 9); + strncpy(current_pin, (char *)blobmsg_data(tb[CURRENT_PIN]), 9); + validate_pin_format(new_pin); + validate_pin_format(current_pin); + + printf("new: %s, old: %s\n", new_pin, current_pin); + char *response = get_csv("pin_status"); + struct json_object *parsed_response = json_tokener_parse(response); + struct json_object *rv; + + json_object_object_get_ex(parsed_response, "pin_status", &rv); + if (!json_object_get_int(rv)) { + response = _enable_pin(current_pin); + json_object_put(parsed_response); + parsed_response = json_tokener_parse(response); + json_object_object_get_ex(parsed_response, "result", &rv); + if (strncmp(json_object_get_string(rv), "failure", strlen("failure")) == 0) { + printf("Incorrect pin!"); + goto print; + } + } + + response = _set_pin(current_pin, new_pin); + json_object_put(parsed_response); + parsed_response = json_tokener_parse(response); + json_object_object_get_ex(parsed_response, "result", &rv); + if (strncmp(json_object_get_string(rv), "failure", strlen("failure")) == 0) { + printf("Incorrect pin!"); + goto print; + } + +print: + print_response(parsed_response, ctx, req); +fail: + return 0; +} + +int disable_pin(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__PIN_MAX]; + char pin[10] = {0}; + + blobmsg_parse(pin_policy, __PIN_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[PIN]) { + printf("Please enter both a new pin and old pin!"); + goto fail; + } + strncpy(pin, (char *)blobmsg_data(tb[PIN]), 9); + validate_pin_format(pin); + + char *response = get_csv("pin_status"); + struct json_object *parsed_response = json_tokener_parse(response); + struct json_object *rv; + + json_object_object_get_ex(parsed_response, "pin_status", &rv); + if (json_object_get_int(rv)) { + response = _disable_pin(pin); + json_object_put(parsed_response); + parsed_response = json_tokener_parse(response); + json_object_object_get_ex(parsed_response, "result", &rv); + if (strncmp(json_object_get_string(rv), "failure", strlen("failure")) == 0) { + printf("Incorrect pin!"); + goto print; + } + } else { + printf("already disabled!\n"); + } + +print: + print_response(parsed_response, ctx, req); +fail: + return 0; +} + +int enable_pin(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_buf bb; + struct blob_attr *tb[__PIN_MAX]; + char pin[10] = {0}; + + blobmsg_parse(pin_policy, __PIN_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[PIN]) { + printf("Please enter both a new pin and old pin!"); + goto fail; + } + + strncpy(pin, (char *)blobmsg_data(tb[PIN]), 9); + validate_pin_format(pin); + + char *response = get_csv("pin_status"); + struct json_object *parsed_response = json_tokener_parse(response); + struct json_object *rv; + + json_object_object_get_ex(parsed_response, "pin_status", &rv); + if (!json_object_get_int(rv)) { + response = _enable_pin(pin); + json_object_put(parsed_response); + parsed_response = json_tokener_parse(response); + json_object_object_get_ex(parsed_response, "result", &rv); + if (strncmp(json_object_get_string(rv), "failure", strlen("failure")) == 0) { + printf("Incorrect pin!"); + goto print; + } + } else { + printf("already enabled!\n"); + } + +print: + print_response(parsed_response, ctx, req); +fail: + return 0; +} + +int verify_pin(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_buf bb; + struct blob_attr *tb[__PIN_MAX]; + char pin[10] = {0}; + + blobmsg_parse(pin_policy, __PIN_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[PIN]) { + printf("Please enter both a new pin and old pin!"); + goto fail; + } + strncpy(pin, (char *)blobmsg_data(tb[PIN]), 9); + validate_pin_format(pin); + + char *response = get_csv("pin_status"); + struct json_object *parsed_response = json_tokener_parse(response); + struct json_object *rv; + + json_object_object_get_ex(parsed_response, "pin_status", &rv); + if (json_object_get_string(rv)) { + response = _enable_pin(pin); + } else { + response = _disable_pin(pin); + } + + json_object_put(parsed_response); + parsed_response = json_tokener_parse(response); + + print_response(parsed_response, ctx, req); +fail: + return 0; +} + +int remaining_tries(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_buf bb; + char *response = get_csv("pinnumber"); + struct json_object *parsed_response = json_tokener_parse(response); + print_response(parsed_response, ctx, req); + return 0; +} + +struct ubus_method dongle_object_methods[] = { + UBUS_METHOD("set_pin", set_pin, set_pin_policy), + UBUS_METHOD("disable_pin", disable_pin, pin_policy), + UBUS_METHOD("enable_pin", enable_pin, pin_policy), + UBUS_METHOD("verify_pin", verify_pin, pin_policy), + UBUS_METHOD_NOARG("remaining_tries", remaining_tries), +}; + +struct ubus_object_type dongle_object_type = UBUS_OBJECT_TYPE("dongle", dongle_object_methods); + +struct ubus_object dongle_object = { + .name = "dongle.pin", + .type = &dongle_object_type, + .methods = dongle_object_methods, + .n_methods = ARRAY_SIZE(dongle_object_methods), +}; + +void init_ubus(void) +{ + ctx = ubus_connect(NULL); + if (!ctx) { + perror("ubus"); + exit(1); + } + ubus_add_uloop(ctx); +} + +int main(int argc, char **argv) +{ + uloop_init(); + init_ubus(); + ubus_add_object(ctx, &dongle_object); + uloop_run(); + + return 0; +} diff --git a/zte-mf823/libmobile.c b/zte-mf823/libmobile.c new file mode 100644 index 0000000000000000000000000000000000000000..cb97ac49035cf5d4f95785c2144c4c95d93a48c9 --- /dev/null +++ b/zte-mf823/libmobile.c @@ -0,0 +1,391 @@ +#include "libmobile.h" + +struct string { + char *ptr; + size_t len; +}; + +void curl_cleaner(CURLcode *curl) +{ + curl_easy_cleanup(curl); + curl_global_cleanup(); +} + +size_t write_func(void *buffer, size_t size, size_t nmemb, void *userp) +{ + struct string *str = (struct string *)userp; + size_t new_len = str->len + (size * nmemb); + + str->ptr = realloc(str->ptr, new_len + 1); + if (str->ptr == NULL) { + printf("not enough ptr (realloc returned NULL)\n"); + return 0; + } + memcpy(str->ptr + str->len, buffer, size * nmemb); + str->ptr[new_len] = '\0'; + str->len = new_len; + + return size * nmemb; +} + +struct json_object *get_apn_profiles_json(void) +{ + CURL *curl; + CURLcode res; + struct string str; + + str.ptr = calloc(1, 1); + str.len = 0; + curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_get_cmd_process?isTest=false&cmd=APN_config0,APN_config1,APN_config2,APN_config3,APN_config4,APN_config5,APN_config6,APN_config7,APN_config8,APN_config9,APN_config10,APN_config11,APN_config12,APN_config13,APN_config14,APN_config15,APN_config16,APN_config17,APN_config18,APN_config19&multi_data=1"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + struct json_object *apn_profiles = json_tokener_parse(str.ptr); + +fail: + curl_cleaner(curl); + return apn_profiles; +} + +struct blob_buf json_to_blob(struct json_object *response, struct blob_buf bb) +{ + void *arr, *obj; + int i; + + json_object_object_foreach(response, key, val) { + int val_type = json_object_get_type(val); + + switch (val_type) { + case json_type_int: + blobmsg_add_u32(&bb, key, json_object_get_int(val)); + break; + case json_type_double: + blobmsg_add_double(&bb, key, json_object_get_double(val)); + break; + case json_type_string: + blobmsg_add_string(&bb, key, json_object_get_string(val)); + break; + case json_type_array: + arr = blobmsg_open_array(&bb, key); + for (i = 0; i < json_object_array_length(val); i++) + bb = json_to_blob(json_object_array_get_idx(val, i), bb); + blobmsg_close_array(&bb, arr); + break; + case json_type_object: + obj = blobmsg_open_table(&bb, key); + bb = json_to_blob(val, bb); + blobmsg_close_array(&bb, obj); + break; + } + } + + return bb; +} + +int get_apn_profiles_len(void) +{ + struct json_object *apn_profiles = get_apn_profiles_json(); + int len = 0; + + json_object_object_foreach(apn_profiles, key, val) { + if (strlen(json_object_get_string(val)) > 0) + len++; + else + return len; + } + + json_object_put(apn_profiles); + return -1; +} + +int _delete_apn(int idx, char *response) +{ + CURL *curl; + CURLcode res; + char post_query[1024]; + struct string str; + + str.ptr = calloc(1, 1); + str.len = 0; + + printf("index we are attempting to remove: %d\n", idx); + post_query[0] = '\0'; + strncpy(post_query, "isTest=false&apn_action=delete&apn_mode=manual&index=", 1023); + sprintf(post_query + strlen(post_query), "%d", idx); + strncat(post_query + strlen(post_query), "&goformId=APN_PROC_EX", 1023); + + printf("post_query: %s\n", post_query); + + curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_set_cmd_process"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_query); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + printf("%s\n", str.ptr); + strncpy(response, str.ptr, 1023); + return 0; +fail: + return -1; +} + +int get_apn_profile_idx(struct json_object *apn_profiles, char *name) +{ + int idx = 0; + + json_object_object_foreach(apn_profiles, key, val) { + char *apn_profile = json_object_get_string(val); + char *apn_name = strtok(apn_profile, "($)"); + + if (strncmp(apn_name, name, 1024) == 0) + return idx; + idx++; + } + return -1; +} + +char *get_current_wan_apn(void) +{ + CURL *curl; + CURLcode res; + struct string str; + + str.ptr = calloc(1, 1); + str.len = 0; + curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_get_cmd_process?isTest=false&cmd=wan_apn&multi_data=1"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + return str.ptr; +fail: + return NULL; +} + +char *_create_apn_profile(char *apn) +{ + CURL *curl; + CURLcode res; + char post_query[1024]; + struct string str; + + str.ptr = calloc(1, 1); + str.len = 0; + + post_query[0] = '\0'; + strncpy(post_query, "isTest=false&goformId=APN_PROC_EX&apn_action=save&apn_mode=manual&profile_name=", 1023); + strncat(post_query + strlen(post_query), apn, 1023); + strncat(post_query + strlen(post_query), "&wan_dial=*99%23&apn_select=manual&pdp_type=IP&pdp_select=auto&pdp_addr=&index=", 1023); + sprintf(post_query + strlen(post_query), "%d", get_apn_profiles_len()); + strncat(post_query + strlen(post_query), "&wan_apn=", 1023); + strncat(post_query + strlen(post_query), apn, 1023); + strncat(post_query + strlen(post_query), "&ppp_auth_mode=none&ppp_username=&ppp_passwd=&dns_mode=auto&prefer_dns_manual=&standby_dns_manual=", 1023); + printf("post_query: %s\n", post_query); + + curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_set_cmd_process"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_query); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + return str.ptr; +fail: + return NULL; +} + +char *_set_apn_profile(int idx) +{ + CURL *curl; + CURLcode res; + char post_query[1024]; + struct string str; + + str.ptr = calloc(1, 1); + str.len = 0; + post_query[0] = '\0'; + strncpy(post_query, "isTest=false&goformId=APN_PROC_EX&apn_mode=manual&apn_action=set_default&set_default_flag=1&pdp_type=IP&index=", 1023); + sprintf(post_query + strlen(post_query), "%d", idx); + printf("post_query: %s\n", post_query); + + curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_set_cmd_process"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_query); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + return str.ptr; +fail: + return NULL; +} + +char *get_csv(char *csv) +{ + CURL *curl; + CURLcode res; + struct string str; + char get_query[1024]; + + str.ptr = calloc(1, 1); + str.len = 0; + curl = curl_easy_init(); + + strncpy(get_query, "http://192.168.0.1/goform/goform_get_cmd_process?isTest=false&cmd=", 1023); + strncat(get_query + strlen(get_query), csv, 1023); + strncat(get_query, "&multi_data=1", 1023); + + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, get_query); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + return str.ptr; +fail: + return NULL; +} + +char *_enable_pin(char *pin) +{ + CURL *curl; + CURLcode res; + struct string str; + char post_query[1024]; + + str.ptr = calloc(1, 1); + str.len = 0; + curl = curl_easy_init(); + + strncpy(post_query, "goformId=ENABLE_PIN&OldPinNumber=", 1023); + strncat(post_query + strlen(post_query), pin, 1023); + strncat(post_query + strlen(post_query), "&pin_save_flag=0&isTest=false", 1023); + + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_set_cmd_process"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_query); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) + { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + return str.ptr; +fail: + return NULL; +} + +char *_set_pin(char *current_pin, char *new_pin) +{ + CURL *curl; + CURLcode res; + struct string str; + char post_query[1024]; + + str.ptr = calloc(1, 1); + str.len = 0; + curl = curl_easy_init(); + + strncpy(post_query, "goformId=ENABLE_PIN&OldPinNumber=", 1023); + strncat(post_query + strlen(post_query), current_pin, 1023); + strncat(post_query + strlen(post_query), "&NewPinNumber=", 1023); + strncat(post_query + strlen(post_query), new_pin, 1023); + strncat(post_query + strlen(post_query), "&pin_save_flag=0&isTest=false", 1023); + + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_set_cmd_process"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_query); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + return str.ptr; +fail: + return NULL; +} + +char *_disable_pin(char *pin) +{ + CURL *curl; + CURLcode res; + struct string str; + char post_query[1024] = {0}; + + str.ptr = calloc(1, 1); + str.len = 0; + curl = curl_easy_init(); + + strncpy(post_query, "goformId=DISABLE_PIN&OldPinNumber=", 1023); + strncat(post_query + strlen(post_query), pin, 1023); + strncat(post_query + strlen(post_query), "&pin_save_flag=0&isTest=false", 1023); + + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.1/goform/goform_set_cmd_process"); + curl_easy_setopt(curl, CURLOPT_REFERER, "http://192.168.0.1/index.html"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_query); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str); + res = curl_easy_perform(curl); + if (res) { + printf("errored when performing curl, %s\n", curl_easy_strerror(res)); + goto fail; + } + } + return str.ptr; +fail: + return NULL; +}