/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 * * 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. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /***************************************************************************** Source device.c Version 0.1 Date 2012/11/29 Product NAS stack Subsystem Utilities Author Frederic Maurel Description Implements Linux/UNIX I/O device handlers *****************************************************************************/ #include "device.h" #include "commonDef.h" #include // fflush #include // malloc, free #include // strncpy #include // read, write, close #include #include // open /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ /* Function used to configure TTY I/O terminal attributes */ extern int stty_set(int fd, const char *params); /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ /* ------------------------ * Identifier of the device * ------------------------ * A device is defined with a pathname and attribute parameters. * A file descriptor is created to handle the setup of the device * attributes. */ struct device_id_s { #define DEVICE_PATHNAME_SIZE 32 char pathname[DEVICE_PATHNAME_SIZE+1]; /* device pathname */ int fd; /* device file descriptor */ }; /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ /**************************************************************************** ** ** ** Name: device_open() ** ** ** ** Description: Open a device to get a file descriptor for use with read ** ** and write I/O operations ** ** ** ** Inputs: devpath: Device path name ** ** params: Device parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: A pointer to the device identifier alloca- ** ** ted for I/O operations. NULL if the device ** ** has not been successfully opened. ** ** Others: None ** ** ** ***************************************************************************/ void* device_open(int type, const char* devpath, const char* params) { int fd; /* Parameters sanity check */ if (devpath == NULL) { return NULL; } if (type != DEVICE) { return NULL; } /* Open the device for I/O operations */ fd = open(devpath, O_RDWR); if (fd < 0) { return NULL; } /* The device has been successfully opened */ device_id_t * devid = (device_id_t *)malloc(sizeof(struct device_id_s)); if (devid != NULL) { strncpy(devid->pathname, devpath, DEVICE_PATHNAME_SIZE); devid->fd = fd; if (params != NULL) { /* Set TTY parameters */ if (stty_set(fd, params) != RETURNok) { device_close(devid); devid = NULL; close(fd); } } } return devid; } /**************************************************************************** ** ** ** Name: device_close() ** ** ** ** Description: Close the specified device and frees memory space alloca- ** ** ted to handle access to the device ** ** ** ** Inputs: None ** ** Others: None ** ** ** ** Outputs: id: The identifier of the device ** ** Return: None ** ** Others: None ** ** ** ***************************************************************************/ void device_close(void* id) { if (id) { close( ((device_id_t*)id)->fd ); free(id); } } /**************************************************************************** ** ** ** Name: device_read() ** ** ** ** Description: Read data from the given I/O device into the input buffer ** ** of specified length ** ** ** ** Inputs: id: The identifier of the device ** ** len: The number of bytes to read ** ** Others: None ** ** ** ** Outputs: buffer: The input buffer ** ** Return: The number of bytes read when success; ** ** RETURNerror otherwise. ** ** Others: None ** ** ** ***************************************************************************/ ssize_t device_read(void* id, char* buffer, size_t len) { const device_id_t* devid = (device_id_t*)(id); ssize_t rbytes = 0; do { ssize_t size = read(devid->fd, buffer + rbytes, len - rbytes); if (size < 0) { return RETURNerror; } rbytes += size; } while ( (buffer[rbytes-1] != '\r') && (buffer[rbytes-1] != '\n') && (buffer[rbytes-1] != '\0') ); return rbytes; } /**************************************************************************** ** ** ** Name: device_write() ** ** ** ** Description: Write data to the given I/O device from the output buffer ** ** of specified length ** ** ** ** Inputs: id: The identifier of the device ** ** buffer: The output buffer ** ** len: The number of bytes to write ** ** Others: None ** ** ** ** Outputs: None ** ** Return: The number of bytes written when success; ** ** RETURNerror otherwise. ** ** Others: None ** ** ** ***************************************************************************/ ssize_t device_write(const void* id, const char* buffer, size_t len) { const device_id_t* devid = (device_id_t*)(id); ssize_t sbytes = write(devid->fd, buffer, len); fflush(NULL); if (sbytes != len) { return RETURNerror; } return sbytes; } /**************************************************************************** ** ** ** Name: device_get_fd() ** ** ** ** Description: Get the value of the file descriptor created to handle ** ** the device with the given identifier ** ** ** ** Inputs: id: The identifier of the device ** ** Others: None ** ** ** ** Outputs: None ** ** Return: The file descriptor of the device ** ** Others: None ** ** ** ***************************************************************************/ int device_get_fd(const void* id) { if (id) { return ((device_id_t*)id)->fd; } return RETURNerror; } /****************************************************************************/ /********************* L O C A L F U N C T I O N S *********************/ /****************************************************************************/