+ Writef("d%i\r\n", Item);
+
+ // Read empty lines and echo-backs
+ do {
+ ret = ReadLine(sizeof(tmp)-1, tmp);
+ if( ret == -1 ) {
+ pthread_mutex_unlock(&gCoke_Mutex);
+ return -1;
+ }
+ TRACE("read %i '%s'\n", ret, tmp);
+ } while( ret == 0 || tmp[0] == ':' || tmp[0] == 'd' );
+
+ WaitForColon(); // Eat up rest of response
+
+ TRACE("done\n");
+
+ // TODO: Regex instead?
+ if( strcmp(tmp, "ok") == 0 ) {
+ // We think dispense worked
+ // - The machine returns 'ok' if an empty slot is dispensed, even if
+ // it doesn't actually try to dispense (no sound)
+ ret = 0;
+ }
+ else {
+ printf("Coke_DoDispense: Machine returned unknown value '%s'\n", tmp);
+ ret = -1;
+ }
+
+ TRACE("Updating slot status\n");
+
+ // Update status
+ WaitForColon();
+ Writef("s%i\r\n", Item);
+ len = ReadLine(sizeof tmp, tmp);
+ if(len == -1) gaCoke_CachedStatus[Item] = -1;
+ Coke_int_GetSlotStatus(tmp, Item);
+ {
+ char buf[512];
+ read(giCoke_SerialFD, buf, 512); // Flush
+ }
+
+ gtCoke_LastDispenseTime = time(NULL);
+
+ // Release and return
+ pthread_mutex_unlock(&gCoke_Mutex);
+
+ //return ret;
+ // HACK!!!
+ return 0;
+}
+
+char ReadChar()
+{
+ fd_set readfs;
+ char ch = 0;
+ int ret;
+ struct timeval timeout;
+
+ timeout.tv_sec = READ_TIMEOUT;
+ timeout.tv_usec = 0;
+
+ FD_ZERO(&readfs);
+ FD_SET(giCoke_SerialFD, &readfs);
+
+ ret = select(giCoke_SerialFD+1, &readfs, NULL, NULL, &timeout);
+ if( ret == 0 ) {
+ fprintf(stderr, "ReadChar: Timeout of %is expired\n", READ_TIMEOUT);
+ return 0; // Timeout
+ }
+ if( ret != 1 ) {
+ printf("ReadChar: select return %i\n", ret);
+ return 0;
+ }
+
+ ret = read(giCoke_SerialFD, &ch, 1);
+ if( ret != 1 ) {
+ printf("ReadChar: ret != 1 (%i)\n", ret);
+ return 0;
+ }
+
+ return ch;
+}