
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>

#include "vold.h"
#include "uevent.h"
#include "mmc.h"
#include "blkdev.h"
#include "volmgr.h"
#include "media.h"

#define DEBUG_UEVENT 0

#define UEVENT_PARAMS_MAX 32

enum uevent_action { action_add, action_remove, action_change };

struct uevent {
    char *path;
    enum uevent_action action;
    char *subsystem;
    char *param[UEVENT_PARAMS_MAX];
    unsigned int seqnum;
};

struct uevent_dispatch {
    char *subsystem;
    int (* dispatch) (struct uevent *);
};

static void dump_uevent(struct uevent *);
static int dispatch_uevent(struct uevent *event);
static void free_uevent(struct uevent *event);
static char *get_uevent_param(struct uevent *event, char *param_name);

static int handle_powersupply_event(struct uevent *event);
static int handle_switch_event(struct uevent *);
static int handle_battery_event(struct uevent *);
static int handle_mmc_event(struct uevent *);
static int handle_block_event(struct uevent *);
static int handle_bdi_event(struct uevent *);
static void _cb_blkdev_ok_to_destroy(blkdev_t *dev);

static struct uevent_dispatch dispatch_table[] = {
    { "switch", handle_switch_event }, 
    { "battery", handle_battery_event }, 
    { "mmc", handle_mmc_event },
    { "block", handle_block_event },
    { "bdi", handle_bdi_event },
    { "power_supply", handle_powersupply_event },
    { NULL, NULL }
};

static boolean low_batt = false;
static boolean door_open = true;

int process_uevent_message(int socket)
{
    char buffer[64 * 1024]; // Thank god we're not in the kernel :)
    int count;
    char *s = buffer;
    char *end;
    struct uevent *event;
    int param_idx = 0;
    int i;
    int first = 1;
    int rc = 0;

    if ((count = recv(socket, buffer, sizeof(buffer), 0)) < 0) {
        LOGE("Error receiving uevent (%s)", strerror(errno));
        return -errno;
    }

    if (!(event = malloc(sizeof(struct uevent)))) {
        LOGE("Error allocating memory (%s)", strerror(errno));
        return -errno;
    }

    memset(event, 0, sizeof(struct uevent));

    end = s + count;
    while (s < end) {
        if (first) {
            char *p;
            for (p = s; *p != '@'; p++);
            p++;
            event->path = strdup(p);
            first = 0;
        } else {
            if (!strncmp(s, "ACTION=", strlen("ACTION="))) {
                char *a = s + strlen("ACTION=");
               
                if (!strcmp(a, "add"))
                    event->action = action_add;
                else if (!strcmp(a, "change"))
                    event->action = action_change;
                else if (!strcmp(a, "remove"))
                    event->action = action_remove;
            } else if (!strncmp(s, "SEQNUM=", strlen("SEQNUM=")))
                event->seqnum = atoi(s + strlen("SEQNUM="));
            else if (!strncmp(s, "SUBSYSTEM=", strlen("SUBSYSTEM=")))
                event->subsystem = strdup(s + strlen("SUBSYSTEM="));
            else
                event->param[param_idx++] = strdup(s);
        }
        s+= strlen(s) + 1;
    }

    rc = dispatch_uevent(event);
    
    free_uevent(event);
    return rc;
}

int simulate_uevent(char *subsys, char *path, char *action, char **params)
{
    struct uevent *event;
    char tmp[255];
    int i, rc;

    if (!(event = malloc(sizeof(struct uevent)))) {
        LOGE("Error allocating memory (%s)", strerror(errno));
        return -errno;
    }

    memset(event, 0, sizeof(struct uevent));

    event->subsystem = strdup(subsys);

    if (!strcmp(action, "add"))
        event->action = action_add;
    else if (!strcmp(action, "change"))
        event->action = action_change;
    else if (!strcmp(action, "remove"))
        event->action = action_remove;
    else {
        LOGE("Invalid action '%s'", action);
        return -1;
    }

    event->path = strdup(path);

    for (i = 0; i < UEVENT_PARAMS_MAX; i++) {
        if (!params[i])
            break;
        event->param[i] = strdup(params[i]);
    }

    rc = dispatch_uevent(event);
    free_uevent(event);
    return rc;
}

static int dispatch_uevent(struct uevent *event)
{
    int i;

#if DEBUG_UEVENT
    dump_uevent(event);
#endif
    for (i = 0; dispatch_table[i].subsystem != NULL; i++) {
        if (!strcmp(dispatch_table[i].subsystem, event->subsystem))
            return dispatch_table[i].dispatch(event);
    }

#if DEBUG_UEVENT
    LOG_VOL("No uevent handlers registered for '%s' subsystem", event->subsystem);
#endif
    return 0;
}

static void dump_uevent(struct uevent *event)
{
    int i;

    LOG_VOL("[UEVENT] Sq: %u S: %s A: %d P: %s",
              event->seqnum, event->subsystem, event->action, event->path);
    for (i = 0; i < UEVENT_PARAMS_MAX; i++) {
        if (!event->param[i])
            break;
        LOG_VOL("%s", event->param[i]);
    }
}

static void free_uevent(struct uevent *event)
{
    int i;
    free(event->path);
    free(event->subsystem);
    for (i = 0; i < UEVENT_PARAMS_MAX; i++) {
        if (!event->param[i])
            break;
        free(event->param[i]);
    }
    free(event);
}

static char *get_uevent_param(struct uevent *event, char *param_name)
{
    int i;

    for (i = 0; i < UEVENT_PARAMS_MAX; i++) {
        if (!event->param[i])
            break;
        if (!strncmp(event->param[i], param_name, strlen(param_name)))
            return &event->param[i][strlen(param_name) + 1];
    }

    LOGE("get_uevent_param(): No parameter '%s' found", param_name);
    return NULL;
}

/*
 * ---------------
 * Uevent Handlers
 * ---------------
 */

static int handle_powersupply_event(struct uevent *event)
{
    char *ps_type = get_uevent_param(event, "POWER_SUPPLY_TYPE");
    char *ps_cap = get_uevent_param(event, "POWER_SUPPLY_CAPACITY");

    if (!strcasecmp(ps_type, "battery")) {
        int capacity = atoi(ps_cap);
  
        if (capacity < 5)
            low_batt = true;
        else
            low_batt = false;
LOG_VOL("handle_powersupply_event(): low_batt = %d, door_open = %d", low_batt, door_open);
        volmgr_safe_mode(low_batt || door_open);
    }
    return 0;
}

static int handle_switch_event(struct uevent *event)
{
    char *name = get_uevent_param(event, "SWITCH_NAME");
    char *state = get_uevent_param(event, "SWITCH_STATE");


    if (!strcmp(name, "usb_mass_storage")) {
        if (!strcmp(state, "online")) {
            ums_hostconnected_set(true);
        } else {
            ums_hostconnected_set(false);
            volmgr_enable_ums(false);
        }
    } else if (!strcmp(name, "sd-door")) {
        if (!strcmp(state, "open"))
            door_open = true;
        else
            door_open = false;
LOG_VOL("handle_powersupply_event(): low_batt = %d, door_open = %d", low_batt, door_open);
        volmgr_safe_mode(low_batt || door_open);
    } else
        LOG_VOL("handle_switch_event(): Ignoring switch '%s'", name);

    return 0;
}

static int handle_battery_event(struct uevent *event)
{
    return 0;
}

static int handle_block_event(struct uevent *event)
{
    char mediapath[255];
    media_t *media;
    int n;
    int maj, min;
    blkdev_t *blkdev;

    /*
     * Look for backing media for this block device
     */
    if (!strncmp(get_uevent_param(event, "DEVPATH"),
                 "/devices/virtual/",
                 strlen("/devices/virtual/"))) {
        n = 0;
    } else if (!strcmp(get_uevent_param(event, "DEVTYPE"), "disk"))
        n = 2;
    else if (!strcmp(get_uevent_param(event, "DEVTYPE"), "partition"))
        n = 3;
    else {
        LOGE("Bad blockdev type '%s'", get_uevent_param(event, "DEVTYPE"));
        return -EINVAL;
    }

    truncate_sysfs_path(event->path, n, mediapath);

    if (!(media = media_lookup_by_path(mediapath, false))) {
#if DEBUG_UEVENT
        LOG_VOL("No backend media found @ device path '%s'", mediapath);
#endif
        return 0;
    }

    maj = atoi(get_uevent_param(event, "MAJOR"));
    min = atoi(get_uevent_param(event, "MINOR"));

    if (event->action == action_add) {
        blkdev_t *disk;

        /*
         * If there isn't a disk already its because *we*
         * are the disk
         */
        disk = blkdev_lookup_by_devno(maj, 0);

        if (!(blkdev = blkdev_create(disk,
                                     event->path,
                                     maj,
                                     min,
                                     media,
                                     get_uevent_param(event, "DEVTYPE")))) {
            LOGE("Unable to allocate new blkdev (%m)");
            return -1;
        }

        blkdev_refresh(blkdev);

        /*
         * Add the blkdev to media
         */
        int rc;
        if ((rc = media_add_blkdev(media, blkdev)) < 0) {
            LOGE("Unable to add blkdev to card (%d)", rc);
            return rc;
        }

        LOG_VOL("New blkdev %d.%d on media %s, media path %s, Dpp %d",
                blkdev->major, blkdev->minor, media->name, mediapath,
                blkdev_get_num_pending_partitions(blkdev->disk));

        if (blkdev_get_num_pending_partitions(blkdev->disk) == 0) {
            if ((rc = volmgr_consider_disk(blkdev->disk)) < 0) {
                LOGE("Volmgr failed to handle device (%d)", rc);
                return rc;
            }
        }
    } else if (event->action == action_remove) {
        if (!(blkdev = blkdev_lookup_by_devno(maj, min)))
            return 0;

        LOG_VOL("Destroying blkdev %d.%d @ %s on media %s", blkdev->major,
                blkdev->minor, blkdev->devpath, media->name);
        volmgr_notify_eject(blkdev, _cb_blkdev_ok_to_destroy);

    } else if (event->action == action_change) {
        if (!(blkdev = blkdev_lookup_by_devno(maj, min)))
            return 0;

        LOG_VOL("Modified blkdev %d.%d @ %s on media %s", blkdev->major,
                blkdev->minor, blkdev->devpath, media->name);
        
        blkdev_refresh(blkdev);
    } else  {
#if DEBUG_UEVENT
        LOG_VOL("No handler implemented for action %d", event->action);
#endif
    }
    return 0;
}

static void _cb_blkdev_ok_to_destroy(blkdev_t *dev)
{
    media_t *media = media_lookup_by_dev(dev);
    if (media)
        media_remove_blkdev(media, dev);
    blkdev_destroy(dev);
}

static int handle_bdi_event(struct uevent *event)
{
    return 0;
}

static int handle_mmc_event(struct uevent *event)
{
    if (event->action == action_add) {
        media_t *media;
        char serial[80];
        char *type;

        /*
         * Pull card information from sysfs
         */
        type = get_uevent_param(event, "MMC_TYPE");
        if (strcmp(type, "SD") && strcmp(type, "MMC"))
            return 0;
        
        read_sysfs_var(serial, sizeof(serial), event->path, "serial");
        if (!(media = media_create(event->path,
                                   get_uevent_param(event, "MMC_NAME"),
                                   serial,
                                   media_mmc))) {
            LOGE("Unable to allocate new media (%m)");
            return -1;
        }
        LOG_VOL("New MMC card '%s' (serial %u) added @ %s", media->name,
                  media->serial, media->devpath);
    } else if (event->action == action_remove) {
        media_t *media;

        if (!(media = media_lookup_by_path(event->path, false))) {
            LOGE("Unable to lookup media '%s'", event->path);
            return -1;
        }

        LOG_VOL("MMC card '%s' (serial %u) @ %s removed", media->name, 
                  media->serial, media->devpath);
        media_destroy(media);
    } else {
#if DEBUG_UEVENT
        LOG_VOL("No handler implemented for action %d", event->action);
#endif
    }

    return 0;
}
