int Server_Read(int inum, char *buffer, int block){ Data_Init(); if(Inode_BitMap.bits[inum] == false){ return -1; } if(block < 0 || block > 9){ return -1; }else if(inode_table[inum].ptr[block] == -1){ return -1; } int to_read_block = inode_table[inum].ptr[block]; int j; for(j = 0; j < MFS_BLOCK_SIZE; j++){ buffer[j] = data_region[to_read_block].data[j]; } return 0; }
/** * Add and initialise an Actuator * @param name - Human readable name of the actuator * @param read - Function to call whenever the actuator should be read * @param init - Function to call to initialise the actuator (may be NULL) * @returns Number of actuators added so far */ int Actuator_Add(const char * name, int user_id, SetFn set, InitFn init, CleanFn cleanup, SanityFn sanity, double initial_value) { if (++g_num_actuators > ACTUATORS_MAX) { Fatal("Too many sensors; Increase ACTUATORS_MAX from %d in actuator.h and recompile", ACTUATORS_MAX); } Actuator * a = &(g_actuators[g_num_actuators-1]); a->id = g_num_actuators-1; a->user_id = user_id; Data_Init(&(a->data_file)); a->name = name; a->set = set; // Set read function a->init = init; // Set init function a->sanity = sanity; pthread_mutex_init(&(a->mutex), NULL); if (init != NULL) { if (!init(name, user_id)) Fatal("Couldn't initialise actuator %s", name); } Actuator_SetValue(a, initial_value, false); return g_num_actuators; }
int Server_Creat(int pinum, int type, char *name){ Data_Init(); if(Inode_BitMap.bits[pinum] == false || inode_table[pinum].type != MFS_DIRECTORY){ return -1; } if(Server_LookUp(pinum,name) >= 0){ return 0; } int inum = First_Empty(&Inode_BitMap); Set_Bit(&Inode_BitMap, inum); if(Add_Entry(pinum, inum, name, inode_table, data_region) != 0){ fprintf(stderr,"add entry error\n"); } if(type == MFS_REGULAR_FILE){ inode_table[inum].type = type; inode_table[inum].size = 0; inode_table[inum].blocks = 0; int i; for(i = 0; i < MFS_PTR_NUMS; i++){ inode_table[inum].ptr[i] = -1; } } if(type == MFS_DIRECTORY){ int to_write_block = First_Empty(&Data_BitMap); Set_Bit(&Data_BitMap,to_write_block); inode_table[inum].type = type; inode_table[inum].size = 2 * sizeof(MFS_DirEnt_t); inode_table[inum].blocks = 1; inode_table[inum].ptr[0] = to_write_block; int i; for(i = 1; i < MFS_PTR_NUMS; i++){ inode_table[inum].ptr[i] = -1; } MFS_DirEnt_t * entries = (MFS_DirEnt_t *) data_region[to_write_block].data; entries[0].inum = inum; strcpy(entries[0].name, "."); entries[1].inum = pinum; strcpy(entries[1].name, ".."); for(i = 2; i < MFS_BLOCK_SIZE / sizeof(MFS_DirEnt_t); i++){ entries[i].inum = -1; } } Data_Write(); return 0; }
int Server_Stat(int inum, MFS_Stat_t *m){ Data_Init(); if(Inode_BitMap.bits[inum] == false){ return -1; } m -> type = inode_table[inum].type; m -> size = inode_table[inum].size; m -> blocks = inode_table[inum].blocks; return 0; }
int Server_Write(int inum, char * buffer, int block){ int i; Data_Init(); if(Inode_BitMap.bits[inum] == false){ return -1; } if(inode_table[inum].type != MFS_REGULAR_FILE){ return -1; } if(block < 0 || block > 9){ return -1; } int to_write_block; if(inode_table[inum].ptr[block] == -1){ to_write_block = First_Empty(&Data_BitMap); Set_Bit(&Data_BitMap,to_write_block); for(i = 0; i <= block; i++){ if(inode_table[inum].ptr[i] == -1){ inode_table[inum].size += MFS_BLOCK_SIZE; inode_table[inum].blocks ++; } } inode_table[inum].ptr[block] = to_write_block; }else{ to_write_block = inode_table[inum].ptr[block]; } for(i = 0; i < MFS_BLOCK_SIZE; i++){ data_region[to_write_block].data[i] = buffer[i]; } Data_Write(); return 0; }
int Server_LookUp(int pinum, char *name){ if(pinum < 0){ return -1; } int idx; Data_Init(); //return -2 if invalid pinum if(Inode_BitMap.bits[pinum] == false){ return -1; }else if(inode_table[pinum].type != MFS_DIRECTORY){ return -1; } int curr_blk_num; for(idx = 0; idx < MFS_PTR_NUMS; idx++){ if((curr_blk_num = inode_table[pinum].ptr[idx]) == -1){ continue; } int entries_in_curr_blk = MFS_BLOCK_SIZE / sizeof(MFS_DirEnt_t); MFS_DirEnt_t *entries = (MFS_DirEnt_t *)data_region[curr_blk_num].data; int j; for (j = 0; j < entries_in_curr_blk; j++){ if(entries[j].inum == -1){ continue; } if(strcmp(entries[j].name, name) == 0){ return entries[j].inum; } } } //return -3 if name doesn't exist in pinum return -1; }
int Server_Unlink(int pinum, char *name){ Data_Init(); if(Inode_BitMap.bits[pinum] == false){ return -1; } if(inode_table[pinum].type != MFS_DIRECTORY){ return -1; } int inum = Server_LookUp(pinum, name); if(inum < 0){ return 0; } if(inode_table[inum].type == MFS_DIRECTORY){ if(inode_table[inum].size > 2 * sizeof(MFS_DirEnt_t)){ return -1; } } int i; for(i = 0; i < MFS_PTR_NUMS; i++){ if(inode_table[inum].ptr[i] != -1){ Unset_Bit(&Data_BitMap, inode_table[inum].ptr[i]); } } Unset_Bit(&Inode_BitMap, inum); Remove_Entry(pinum, inum, name, inode_table, data_region); Data_Write(); return 0; }
/** * Add and initialise a Sensor * @param name - Human readable name of the sensor * @param user_id - User identifier * @param read - Function to call whenever the sensor should be read * @param init - Function to call to initialise the sensor (may be NULL) * @param max_error - Maximum error threshold; program will exit if this is exceeded for the sensor reading * @param min_error - Minimum error threshold; program will exit if the sensor reading falls below this value * @param max_warn - Maximum warning threshold; program will log warnings if the value exceeds this threshold * @param min_warn - Minimum warning threshold; program will log warnings if the value falls below this threshold * @returns Number of actuators added so far */ int Sensor_Add(const char * name, int user_id, ReadFn read, InitFn init, CleanFn cleanup, SanityFn sanity) { if (++g_num_sensors > SENSORS_MAX) { Fatal("Too many sensors; Increase SENSORS_MAX from %d in sensor.h and recompile", SENSORS_MAX); // We could design the program to use realloc(3) // But since someone who adds a new sensor has to recompile the program anyway... } Sensor * s = &(g_sensors[g_num_sensors-1]); s->id = g_num_sensors-1; s->user_id = user_id; Data_Init(&(s->data_file)); s->name = name; s->read = read; // Set read function s->init = init; // Set init function // Start by averaging values taken over a second DOUBLE_TO_TIMEVAL(1, &(s->sample_time)); s->averages = 1; s->num_read = 0; // Set sanity function s->sanity = sanity; if (init != NULL) { if (!init(name, user_id)) Fatal("Couldn't init sensor %s", name); } s->current_data.time_stamp = 0; s->current_data.value = 0; s->averaged_data.time_stamp = 0; s->averaged_data.value = 0; return g_num_sensors; }