diff --git a/dongle_callbacks.c b/dongle_callbacks.c new file mode 100644 index 0000000000000000000000000000000000000000..00ac693d3193beffb0ba4b0048e4dc0c9d38b975 --- /dev/null +++ b/dongle_callbacks.c @@ -0,0 +1,782 @@ +#include "dongle_callbacks.h" + +//dongle pin.. +static int isdigits(const char *pin); +static int validate_pin_format(char *pin); + + +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}, +}; + +const struct blobmsg_policy unlock_policy[__UNLOCK_MAX] = { + [UNLOCK_PIN] = {.name = "pin", .type = BLOBMSG_TYPE_STRING}, + [PUK] = {.name = "puk", .type = BLOBMSG_TYPE_STRING}, +}; + +static int isdigits(const char *pin) +{ + while (*pin) { + if (isdigit(*pin++) == 0) + return false; + } + return true; +} + +static int validate_puk_format(char *puk) +{ + if (!isdigits(puk)) { + debug_print("Please enter digits only!\n"); + goto fail; + } else if (strlen(puk) == 8) { + debug_print("Please enter 8 digits!\n"); + goto fail; + } + + return 0; +fail: + return -1; +} + +static int validate_pin_format(char *pin) +{ + if (!isdigits(pin)) { + debug_print("Please enter digits only!\n"); + goto fail; + } else if (strlen(pin) > 8 || strlen(pin) < 4) { + debug_print("Please enter between 4 to 8 digits!\n"); + goto fail; + } else if (atoi(pin) == 0) { + debug_print("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_attr *tb[__SET_PIN_MAX]; + char *new_pin, *current_pin, *ip_addr; + int rv; + struct json_object *response, *rv_json; + + blobmsg_parse(set_pin_policy, __SET_PIN_MAX, tb, blob_data(msg), blob_len(msg)); + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + if (!tb[NEW_PIN] && !tb[CURRENT_PIN]) { + debug_print("Please enter both a new pin and old pin!\n"); + goto fail_input; + } + new_pin = (char *)blobmsg_data(tb[NEW_PIN]); + current_pin = (char *)blobmsg_data(tb[CURRENT_PIN]); + + rv = validate_pin_format(new_pin); + if (rv > 0) { + debug_print("invalid pin format\n"); + goto fail_input; + } + + rv = validate_pin_format(current_pin); + if (rv > 0) { + debug_print("invalid pin format\n"); + goto fail_input; + } + + response = mobile_get_pin_status(ip_addr); + if (!response) { + debug_print("error getting pin_status\n"); + goto fail_data; + } + + json_object_object_get_ex(response, "pin_status", &rv_json); + if (!rv_json) { + debug_print("no pin_status available\n"); + goto fail_result; + } + + /* Enable PIN if it is disabled */ + if (!json_object_get_int(rv_json)) { + json_object_put(response); + + response = mobile_enable_pin(ip_addr, current_pin); + if (!response) { + debug_print("error enabling pin!\n"); + goto fail_unknown; + } + + json_object_object_get_ex(response, "result", &rv_json); + if (!rv_json) { + debug_print("error getting result!\n"); + goto fail_result; + } + + if (strncmp(json_object_get_string(rv_json), "failure", strlen("failure")) == 0) { + debug_print("Incorrect pin!\n"); + goto incorrect_pin; + } + } + + json_object_put(response); + response = mobile_set_pin(ip_addr, current_pin, new_pin); + if (!response) { + debug_print("error setting pin!\n"); + goto fail_data; + } + + json_object_object_get_ex(response, "result", &rv_json); + if (!rv_json) { + debug_print("no result available from %s!", __func__); + goto fail_result; + } + +incorrect_pin: + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_input: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_data: + free(ip_addr); + return UBUS_STATUS_NO_DATA; +fail_result: + free(ip_addr); + json_object_put(response); + return UBUS_STATUS_UNKNOWN_ERROR; +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +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, *ip_addr; + int rv; + struct json_object *response, *rv_json; + + blobmsg_parse(pin_policy, __PIN_MAX, tb, blob_data(msg), blob_len(msg)); + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + if (!tb[PIN]) { + debug_print("Please enter a pin!\n"); + goto fail_input; + } + pin = (char *)blobmsg_data(tb[PIN]); + rv = validate_pin_format(pin); + if (rv < 0) { + debug_print("invalid pin format!\n"); + goto fail_input; + } + + response = mobile_get_pin_status(ip_addr); + if (!response) { + debug_print("no response from get_pin_status!\n"); + goto fail_data; + } + + json_object_object_get_ex(response, "pin_status", &rv_json); + if (!rv_json) { + debug_print("no pin_status available in response!\n"); + goto fail_result; + } + + if (!json_object_get_int(rv_json)) { + debug_print("already disabled!\n"); + goto success; //kind of... + } + + json_object_put(response); + response = mobile_disable_pin(ip_addr, pin); + if (!response) { + debug_print("error disabling pin!\n"); + goto fail_data; + } + + json_object_object_get_ex(response, "result", &rv_json); + if (!rv_json) { + debug_print("no result available in response!\n"); + goto fail_result; + } + + if (strncmp(json_object_get_string(rv_json), "failure", strlen("failure")) == 0) + debug_print("Incorrect pin!\n"); + +success: + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_input: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_data: + free(ip_addr); + return UBUS_STATUS_NO_DATA; +fail_result: + free(ip_addr); + json_object_put(response); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +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_attr *tb[__PIN_MAX]; + char *pin, *ip_addr; + int rv; + struct json_object *response, *rv_json; + + blobmsg_parse(pin_policy, __PIN_MAX, tb, blob_data(msg), blob_len(msg)); + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + if (!tb[PIN]) { + debug_print("Please enter both a new pin and old pin!\n"); + goto fail_input; + } + + pin = (char *)blobmsg_data(tb[PIN]); + rv = validate_pin_format(pin); + if (rv < 0) { + debug_print("invalid pin format!\n"); + goto fail_input; + } + + response = mobile_get_pin_status(ip_addr); + if (!response) { + debug_print("no response from get_pin_status!\n"); + goto fail_data; + } + + json_object_object_get_ex(response, "pin_status", &rv_json); + if (!rv_json) { + debug_print("no pin_status available in response!\n"); + goto fail_result; + } + if (!json_object_get_int(rv_json)) { + debug_print("already enabled!\n"); + goto success; + } + + json_object_put(response); + response = mobile_enable_pin(ip_addr, pin); + if (!response) { + debug_print("no response from get_pin_status!\n"); + goto fail_data; + } + + json_object_object_get_ex(response, "result", &rv_json); + if (!rv_json) { + debug_print("no result available in response!\n"); + goto fail_result; + } + + if (strncmp(json_object_get_string(rv_json), "failure", strlen("failure")) == 0) + debug_print("Incorrect pin!\n"); + +success: + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_input: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_data: + free(ip_addr); + return UBUS_STATUS_NO_DATA; +fail_result: + free(ip_addr); + json_object_put(response); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +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_attr *tb[__PIN_MAX]; + char *pin, *ip_addr; + int rv; + struct json_object *response; + + blobmsg_parse(pin_policy, __PIN_MAX, tb, blob_data(msg), blob_len(msg)); + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + if (!tb[PIN]) { + debug_print("Please enter a pin\n!"); + goto fail_input; + } + + pin = (char *)blobmsg_data(tb[PIN]); + rv = validate_pin_format(pin); + if (rv < 0) { + debug_print("invalid pin format!\n"); + goto fail_input; + } + + response = mobile_set_pin(ip_addr, pin, pin); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_input: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int remaining_tries(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + response = mobile_get_remaining_tries(ip_addr); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int unlock_sim(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__UNLOCK_MAX]; + char *pin, *puk, *ip_addr; + struct json_object *response;//, *rv_json; + int rv; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + /*response = mobile_get_remaining_tries(ip_addr); + if (!response) + goto fail_unknown; +*/ + /*json_object_object_get_ex(response, "pinnumber", &rv_json); + if (json_object_get_int(rv_json) > 0) + goto fail_unknown; +*/ + if (!tb[PUK] || !tb[UNLOCK_PIN]) { + debug_print("Please enter both a pin and a puk code!\n"); + goto fail_input; + } + puk = (char *)blobmsg_data(tb[PUK]); + pin = (char *)blobmsg_data(tb[UNLOCK_PIN]); + + rv = validate_pin_format(pin); + if (rv < 0) + goto fail_input; + + rv = validate_puk_format(puk); + if (rv < 0) + goto fail_input; + + response = mobile_unlock_sim(ip_addr, puk, pin); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_input: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +//dongle_apn.. +const struct blobmsg_policy apn_policy[__APN_MAX] = { + [APN_NAME] = {.name = "profile_name", .type = BLOBMSG_TYPE_STRING} +}; + +const struct blobmsg_policy create_apn_policy[__CREATE_MAX] = { + [PROFILE_NAME] = {.name = "profile_name", .type = BLOBMSG_TYPE_STRING}, + [WAN_APN] = {.name = "wan_apn", .type = BLOBMSG_TYPE_STRING}, + [PDP_TYPE] = {.name = "pdp_type", .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) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + response = mobile_get_apn_profiles(ip_addr); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +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 blob_attr *tb[__APN_MAX]; + char *name, *ip_addr; //what is max available name length in dongle? + struct json_object *response; + + blobmsg_parse(apn_policy, __APN_MAX, tb, blob_data(msg), blob_len(msg)); + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + if (!tb[APN_NAME]) + goto fail_argument; + + name = (char *)blobmsg_data(tb[APN_NAME]); + if (strlen(name) == 0) { + debug_print("Empty is not a name!\n"); + goto fail_argument; + } else if (strlen(name) > 1023) { + debug_print("name too long!\n"); + goto fail_argument; + } + + response = mobile_delete_apn(ip_addr, name); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_argument: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +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 blob_attr *tb[__APN_MAX]; + char *name, *ip_addr; + struct json_object *response; + + blobmsg_parse(apn_policy, __APN_MAX, tb, blob_data(msg), blob_len(msg)); + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + if (!tb[APN_NAME]) + goto fail_argument; + + name = (char *)blobmsg_data(tb[APN_NAME]); + if (strlen(name) == 0) { + debug_print("Empty is not a name!\n"); + goto fail_argument; + } else if (strlen(name) > 1023) { + debug_print("name too long!\n"); + goto fail_argument; + } + + response = mobile_set_apn_profile(ip_addr, name); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_argument: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +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[__CREATE_MAX]; + char *profile_name, *wan_apn, *pdp_type, *ip_addr; //what is max available name length in dongle? + struct json_object *response; + + blobmsg_parse(create_apn_policy, __CREATE_MAX, tb, blob_data(msg), blob_len(msg)); + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + if (!tb[PROFILE_NAME] || !tb[WAN_APN] || !tb[PDP_TYPE]) { + debug_print("Need to provide all arguments!\n"); + goto fail_argument; + } + + profile_name = (char *)blobmsg_data(tb[PROFILE_NAME]); + wan_apn = (char *)blobmsg_data(tb[WAN_APN]); + pdp_type = (char *)blobmsg_data(tb[PDP_TYPE]); + if (strlen(profile_name) > 1023 || strlen(wan_apn) > 1023 || strlen(pdp_type) > 1023) { + debug_print("input may be max 1023 characters!\n"); + goto fail_argument; + } else if (strlen(profile_name) <= 0 || strlen(wan_apn) <= 0 || strlen(pdp_type) <= 0) { + debug_print("Empty string is not a valid input!\n"); + goto fail_argument; + } + + response = mobile_create_apn_profile(ip_addr, profile_name, wan_apn, pdp_type); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_argument: + free(ip_addr); + return UBUS_STATUS_INVALID_ARGUMENT; +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +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 *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + + response = mobile_get_current_apn(ip_addr); + + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +//dongle_network.. + +char *dongle_ip; + +int get_signal_strength(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + response = mobile_get_rssi(ip_addr); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); + +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int connect_network(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + response = mobile_connect_network(ip_addr); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); + +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int disconnect(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + response = mobile_disconnect_network(ip_addr); + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); + +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int modem_state(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + response = mobile_get_modem_state(ip_addr); + + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); + +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int enable_roaming(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + response = mobile_enable_roaming(ip_addr); + + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); + +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int disable_roaming(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + response = mobile_disable_roaming(ip_addr); + + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); + +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + +int roam_status(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *ip_addr; + struct json_object *response; + + ip_addr = strdup("192.168.0.1"); + if (!ip_addr) + goto fail_strdup; + response = mobile_get_roam_status(ip_addr); + + if (!response) + goto fail_unknown; + + free(ip_addr); + return print_to_ubus(response, ctx, req); + +fail_unknown: + free(ip_addr); +fail_strdup: + return UBUS_STATUS_UNKNOWN_ERROR; +} + diff --git a/dongle_callbacks.h b/dongle_callbacks.h new file mode 100644 index 0000000000000000000000000000000000000000..e509553dd8b16d72ae39b8056bcba7a17657dd14 --- /dev/null +++ b/dongle_callbacks.h @@ -0,0 +1,37 @@ +#ifndef DONGLE_CALLBACKS_H +#define DONGLE_CALLBACKS_H + +//dongle_pin enum.. +enum { + NEW_PIN, + CURRENT_PIN, + __SET_PIN_MAX +}; + +enum { + PIN, + __PIN_MAX +}; + +enum { + UNLOCK_PIN, + PUK, + __UNLOCK_MAX +}; + +//dongle_apn enum.. +enum { + APN_NAME, + __APN_MAX +}; + +enum { + PROFILE_NAME, + WAN_APN, + PDP_TYPE, + __CREATE_MAX +}; + + +//dongle_network enum(None).. +#endif