GPS的HAL层

GPS接口定义

GpsInterface

/** Represents the standard GPS interface. */
typedef struct {
    /** set to sizeof(GpsInterface) */
    size_t          size;
    /**
     * Opens the interface and provides the callback routines
     * to the implemenation of this interface.
     */
    int   (*init)( GpsCallbacks* callbacks );

    /** Starts navigating. */
    int   (*start)( void );

    /** Stops navigating. */
    int   (*stop)( void );

    /** Closes the interface. */
    void  (*cleanup)( void );

    /** Injects the current time. */
    int   (*inject_time)(GpsUtcTime time, int64_t timeReference,
                         int uncertainty);

    /** Injects current location from another location provider
     *  (typically cell ID).
     *  latitude and longitude are measured in degrees
     *  expected accuracy is measured in meters
     */
    int  (*inject_location)(double latitude, double longitude, float accuracy);

    /**
     * Specifies that the next call to start will not use the
     * information defined in the flags. GPS_DELETE_ALL is passed for
     * a cold start.
     */
    void  (*delete_aiding_data)(GpsAidingData flags);

    /**
     * min_interval represents the time between fixes in milliseconds.
     * preferred_accuracy represents the requested fix accuracy in meters.
     * preferred_time represents the requested time to first fix in milliseconds.
     */
    int   (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
            uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);

    /** Get a pointer to extension information. */
    const void* (*get_extension)(const char* name);
} GpsInterface;

GpsNiInterface

/**
 * Extended interface for Network-initiated (NI) support.
 */
typedef struct
{
    /** set to sizeof(GpsNiInterface) */
    size_t          size;

   /** Registers the callbacks for HAL to use. */
   void (*init) (GpsNiCallbacks *callbacks);

   /** Sends a response to HAL. */
   void (*respond) (int notif_id, GpsUserResponseType user_response);
} GpsNiInterface;

GpsXtraInterface

/** Extended interface for XTRA support. */
typedef struct {
    /** set to sizeof(GpsXtraInterface) */
    size_t          size;
    /**
     * Opens the XTRA interface and provides the callback routines
     * to the implemenation of this interface.
     */
    int  (*init)( GpsXtraCallbacks* callbacks );
    /** Injects XTRA data into the GPS. */
    int  (*inject_xtra_data)( char* data, int length );
} GpsXtraInterface;

AGpsInterface

typedef struct {
    /** set to sizeof(AGpsInterface) */
    size_t          size;

    /**
     * Opens the AGPS interface and provides the callback routines
     * to the implemenation of this interface.
     */
    void  (*init)( AGpsCallbacks* callbacks );
    /**
     * Notifies that a data connection is available and sets 
     * the name of the APN to be used for SUPL.
     */
    int  (*data_conn_open)( const char* apn );
    /**
     * Notifies that the AGPS data connection has been closed.
     */
    int  (*data_conn_closed)();
    /**
     * Notifies that a data connection is not available for AGPS. 
     */
    int  (*data_conn_failed)();
    /**
     * Sets the hostname and port for the AGPS server.
     */
    int  (*set_server)( AGpsType type, const char* hostname, int port );
} AGpsInterface;

gps_device_t

struct gps_device_t {
    struct hw_device_t common;

    /**
     * Set the provided lights to the provided values.
     *
     * Returns: 0 on succes, error code on failure.
     */
    const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev);
};

接口的回调定义

GpsCallbacks

typedef struct {
    /** set to sizeof(GpsCallbacks) */
    size_t      size;
    gps_location_callback location_cb;
    gps_status_callback status_cb;
    gps_sv_status_callback sv_status_cb;
    gps_nmea_callback nmea_cb;
    gps_set_capabilities set_capabilities_cb;
    gps_acquire_wakelock acquire_wakelock_cb;
    gps_release_wakelock release_wakelock_cb;
    gps_create_thread create_thread_cb;
} GpsCallbacks;

GpsNiCallbacks

/** GPS NI callback structure. */
typedef struct
{
    /**
     * Sends the notification request from HAL to GPSLocationProvider.
     */
    gps_ni_notify_callback notify_cb;
    gps_create_thread create_thread_cb;
} GpsNiCallbacks;

GpsXtraCallbacks

typedef struct {
    gps_xtra_download_request download_request_cb;
    gps_create_thread create_thread_cb;
} GpsXtraCallbacks;

AGpsCallbacks

typedef struct {
    agps_status_callback status_cb;
    gps_create_thread create_thread_cb;
} AGpsCallbacks;

GPS模块实现

模块初始化

static struct hw_module_methods_t hw_module_methods = {
    .open = open_gps
};

const struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .version_major = 1,
    .version_minor = 0,
    .id = GPS_HARDWARE_MODULE_ID,
    .name = "lcsapi GPS Module",
    .author = "Broadcom Corporation",
    .methods = &hw_module_methods,
};

open_gps

static int open_gps(const struct hw_module_t* module, char const* name,
                    struct hw_device_t** device)
{
    struct gps_device_t *gps_device = malloc(sizeof(struct gps_device_t));
    if (gps_device)
    {
        memset(gps_device, 0, sizeof(struct gps_device_t));
        gps_device->common.tag        = HARDWARE_DEVICE_TAG;
        gps_device->common.version    = 0;
        gps_device->common.module     = (struct hw_module_t*)module;
        gps_device->get_gps_interface = gps_get_hardware_interface;

        *device = (struct hw_device_t*)gps_device;

        return 0;
    }

    return 1; 
}

gps_get_hardware_interface

const GpsInterface* gps_get_hardware_interface(struct gps_device_t* dev)
{
	return &_GpsInterface;
}

GPS模块的使用

get_gps_interface

static const GpsInterface* get_gps_interface() {
    int err;
    hw_module_t* module;
    const GpsInterface* interface = NULL;

    err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    if (err == 0) {
        hw_device_t* device;
        err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
        if (err == 0) {
            gps_device_t* gps_device = (gps_device_t *)device;
            interface = gps_device->get_gps_interface(gps_device);
        }
    }

    return interface;
}