/[svn]/liblscp/trunk/src/client.c
ViewVC logotype

Diff of /liblscp/trunk/src/client.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 125 by capela, Mon Jun 14 21:04:04 2004 UTC revision 132 by capela, Fri Jun 18 14:19:19 2004 UTC
# Line 28  Line 28 
28    
29  // Local prototypes.  // Local prototypes.
30    
31  static void _lscp_client_set_result (lscp_client_t *pClient, char *pszResult, int iErrno);  static void _lscp_client_evt_proc   (void *pvClient);
 static void _lscp_client_udp_proc   (void *pvClient);  
32    
33    
34  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
35  // Helper functions.  // Event service (datagram oriented).
36    
37  // Result buffer internal settler.  static void _lscp_client_evt_proc ( void *pvClient )
 static void _lscp_client_set_result ( lscp_client_t *pClient, char *pszResult, int iErrno )  
 {  
     if (pClient->pszResult)  
         free(pClient->pszResult);  
     pClient->pszResult = NULL;  
   
     pClient->iErrno = iErrno;  
   
     if (pszResult)  
         pClient->pszResult = strdup(lscp_ltrim(pszResult));  
 }  
   
   
 //-------------------------------------------------------------------------  
 // UDP service (datagram oriented).  
   
 static void _lscp_client_udp_proc ( void *pvClient )  
38  {  {
39      lscp_client_t *pClient = (lscp_client_t *) pvClient;      lscp_client_t *pClient = (lscp_client_t *) pvClient;
40      struct sockaddr_in addr;      struct sockaddr_in addr;
# Line 64  static void _lscp_client_udp_proc ( void Line 46  static void _lscp_client_udp_proc ( void
46      char *pch;      char *pch;
47    
48  #ifdef DEBUG  #ifdef DEBUG
49      fprintf(stderr, "_lscp_client_udp_proc: Client waiting for events.\n");      fprintf(stderr, "_lscp_client_evt_proc: Client waiting for events.\n");
50  #endif  #endif
51    
52      while (pClient->udp.iState) {      while (pClient->evt.iState) {
53          cAddr = sizeof(struct sockaddr_in);          cAddr = sizeof(struct sockaddr_in);
54          cchBuffer = recvfrom(pClient->udp.sock, achBuffer, sizeof(achBuffer), 0, (struct sockaddr *) &addr, &cAddr);          cchBuffer = recvfrom(pClient->evt.sock, achBuffer, sizeof(achBuffer), 0, (struct sockaddr *) &addr, &cAddr);
55          if (cchBuffer > 0) {          if (cchBuffer > 0) {
56  #ifdef DEBUG  #ifdef DEBUG
57              lscp_socket_trace("_lscp_client_udp_proc: recvfrom", &addr, achBuffer, cchBuffer);              lscp_socket_trace("_lscp_client_evt_proc: recvfrom", &addr, achBuffer, cchBuffer);
58  #endif  #endif
59              if (strncasecmp(achBuffer, "PING ", 5) == 0) {              if (strncasecmp(achBuffer, "PING ", 5) == 0) {
60                  // Make sure received buffer it's null terminated.                  // Make sure received buffer it's null terminated.
# Line 87  static void _lscp_client_udp_proc ( void Line 69  static void _lscp_client_udp_proc ( void
69                      if (pClient->sessid && strcmp(pszToken, pClient->sessid) == 0) {                      if (pClient->sessid && strcmp(pszToken, pClient->sessid) == 0) {
70                          sprintf(achBuffer, "PONG %s\r\n", pClient->sessid);                          sprintf(achBuffer, "PONG %s\r\n", pClient->sessid);
71                          cchBuffer = strlen(achBuffer);                          cchBuffer = strlen(achBuffer);
72                          if (sendto(pClient->udp.sock, achBuffer, cchBuffer, 0, (struct sockaddr *) &addr, cAddr) < cchBuffer)                          if (sendto(pClient->evt.sock, achBuffer, cchBuffer, 0, (struct sockaddr *) &addr, cAddr) < cchBuffer)
73                              lscp_socket_perror("_lscp_client_udp_proc: sendto");                              lscp_socket_perror("_lscp_client_evt_proc: sendto");
74  #ifdef DEBUG  #ifdef DEBUG
75                          fprintf(stderr, "> %s", achBuffer);                          fprintf(stderr, "> %s", achBuffer);
76  #endif  #endif
# Line 102  static void _lscp_client_udp_proc ( void Line 84  static void _lscp_client_udp_proc ( void
84                          achBuffer,                          achBuffer,
85                          cchBuffer,                          cchBuffer,
86                          pClient->pvData) != LSCP_OK) {                          pClient->pvData) != LSCP_OK) {
87                      pClient->udp.iState = 0;                      pClient->evt.iState = 0;
88                  }                  }
89              }              }
90          } else {          } else {
91              lscp_socket_perror("_lscp_client_udp_proc: recvfrom");              lscp_socket_perror("_lscp_client_evt_proc: recvfrom");
92              pClient->udp.iState = 0;              pClient->evt.iState = 0;
93          }          }
94      }      }
95    
96  #ifdef DEBUG  #ifdef DEBUG
97      fprintf(stderr, "_lscp_client_udp_proc: Client closing.\n");      fprintf(stderr, "_lscp_client_evt_proc: Client closing.\n");
98  #endif  #endif
99  }  }
100    
# Line 184  lscp_client_t* lscp_client_create ( cons Line 166  lscp_client_t* lscp_client_create ( cons
166      fprintf(stderr, "lscp_client_create: pClient=%p: pszHost=%s iPort=%d.\n", pClient, pszHost, iPort);      fprintf(stderr, "lscp_client_create: pClient=%p: pszHost=%s iPort=%d.\n", pClient, pszHost, iPort);
167  #endif  #endif
168    
169      // Prepare the TCP connection socket...      // Prepare the command connection socket...
170    
171      sock = socket(AF_INET, SOCK_STREAM, 0);      sock = socket(AF_INET, SOCK_STREAM, 0);
172      if (sock == INVALID_SOCKET) {      if (sock == INVALID_SOCKET) {
173          lscp_socket_perror("lscp_client_create: tcp: socket");          lscp_socket_perror("lscp_client_create: cmd: socket");
174          free(pClient);          free(pClient);
175          return NULL;          return NULL;
176      }      }
177    
178  #if defined(WIN32)  #if defined(WIN32)
179      if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)      if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
180          lscp_socket_perror("lscp_client_create: tcp: setsockopt(SO_DONTLINGER)");          lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
181  #endif  #endif
182    
183  #ifdef DEBUG  #ifdef DEBUG
184      lscp_socket_getopts("lscp_client_create: tcp", sock);      lscp_socket_getopts("lscp_client_create: cmd", sock);
185  #endif  #endif
186    
187      cAddr = sizeof(struct sockaddr_in);      cAddr = sizeof(struct sockaddr_in);
# Line 209  lscp_client_t* lscp_client_create ( cons Line 191  lscp_client_t* lscp_client_create ( cons
191      addr.sin_port = htons((short) iPort);      addr.sin_port = htons((short) iPort);
192    
193      if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {      if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
194          lscp_socket_perror("lscp_client_create: tcp: connect");          lscp_socket_perror("lscp_client_create: cmd: connect");
195          closesocket(sock);          closesocket(sock);
196          free(pClient);          free(pClient);
197          return NULL;          return NULL;
198      }      }
199    
200      lscp_socket_agent_init(&(pClient->tcp), sock, &addr, cAddr);      lscp_socket_agent_init(&(pClient->cmd), sock, &addr, cAddr);
201    
202  #ifdef DEBUG  #ifdef DEBUG
203      fprintf(stderr, "lscp_client_create: tcp: pClient=%p: sock=%d addr=%s port=%d.\n", pClient, pClient->tcp.sock, inet_ntoa(pClient->tcp.addr.sin_addr), ntohs(pClient->tcp.addr.sin_port));      fprintf(stderr, "lscp_client_create: cmd: pClient=%p: sock=%d addr=%s port=%d.\n", pClient, pClient->cmd.sock, inet_ntoa(pClient->cmd.addr.sin_addr), ntohs(pClient->cmd.addr.sin_port));
204  #endif  #endif
205    
206      // Prepare the UDP datagram service socket...      // Prepare the event datagram service socket...
207    
208      sock = socket(AF_INET, SOCK_DGRAM, 0);      sock = socket(AF_INET, SOCK_DGRAM, 0);
209      if (sock == INVALID_SOCKET) {      if (sock == INVALID_SOCKET) {
210          lscp_socket_perror("lscp_client_create: udp: socket");          lscp_socket_perror("lscp_client_create: evt: socket");
211          lscp_socket_agent_free(&(pClient->tcp));          lscp_socket_agent_free(&(pClient->cmd));
212          free(pClient);          free(pClient);
213          return NULL;          return NULL;
214      }      }
215    
216      if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)      if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
217          lscp_socket_perror("lscp_client_create: udp: setsockopt(SO_REUSEADDR)");          lscp_socket_perror("lscp_client_create: evt: setsockopt(SO_REUSEADDR)");
218    
219  #ifdef DEBUG  #ifdef DEBUG
220      lscp_socket_getopts("lscp_client_create: udp", sock);      lscp_socket_getopts("lscp_client_create: evt", sock);
221  #endif  #endif
222    
223      cAddr = sizeof(struct sockaddr_in);      cAddr = sizeof(struct sockaddr_in);
# Line 245  lscp_client_t* lscp_client_create ( cons Line 227  lscp_client_t* lscp_client_create ( cons
227      addr.sin_port = htons(0);      addr.sin_port = htons(0);
228    
229      if (bind(sock, (const struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {      if (bind(sock, (const struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
230          lscp_socket_perror("lscp_client_create: udp: bind");          lscp_socket_perror("lscp_client_create: evt: bind");
231          lscp_socket_agent_free(&(pClient->tcp));          lscp_socket_agent_free(&(pClient->cmd));
232          closesocket(sock);          closesocket(sock);
233          free(pClient);          free(pClient);
234          return NULL;          return NULL;
235      }      }
236    
237      if (getsockname(sock, (struct sockaddr *) &addr, &cAddr) == SOCKET_ERROR) {      if (getsockname(sock, (struct sockaddr *) &addr, &cAddr) == SOCKET_ERROR) {
238          lscp_socket_perror("lscp_client_create: udp: getsockname");          lscp_socket_perror("lscp_client_create: evt: getsockname");
239          lscp_socket_agent_free(&(pClient->tcp));          lscp_socket_agent_free(&(pClient->cmd));
240          closesocket(sock);          closesocket(sock);
241          free(pClient);          free(pClient);
242          return NULL;          return NULL;
243      }      }
244    
245      lscp_socket_agent_init(&(pClient->udp), sock, &addr, cAddr);      lscp_socket_agent_init(&(pClient->evt), sock, &addr, cAddr);
246    
247  #ifdef DEBUG  #ifdef DEBUG
248      fprintf(stderr, "lscp_client_create: udp: pClient=%p: sock=%d addr=%s port=%d.\n", pClient, pClient->udp.sock, inet_ntoa(pClient->udp.addr.sin_addr), ntohs(pClient->udp.addr.sin_port));      fprintf(stderr, "lscp_client_create: evt: pClient=%p: sock=%d addr=%s port=%d.\n", pClient, pClient->evt.sock, inet_ntoa(pClient->evt.addr.sin_addr), ntohs(pClient->evt.addr.sin_port));
249  #endif  #endif
250    
251      // No session id, yet.      // No session id, yet.
# Line 292  lscp_client_t* lscp_client_create ( cons Line 274  lscp_client_t* lscp_client_create ( cons
274      lscp_mutex_init(pClient->mutex);      lscp_mutex_init(pClient->mutex);
275    
276      // Now's finally time to startup threads...      // Now's finally time to startup threads...
277      // UDP service thread...      // Event service thread...
278      if (lscp_socket_agent_start(&(pClient->udp), _lscp_client_udp_proc, pClient, 0) != LSCP_OK) {      if (lscp_socket_agent_start(&(pClient->evt), _lscp_client_evt_proc, pClient, 0) != LSCP_OK) {
279          lscp_socket_agent_free(&(pClient->tcp));          lscp_socket_agent_free(&(pClient->cmd));
280          lscp_socket_agent_free(&(pClient->udp));          lscp_socket_agent_free(&(pClient->evt));
281          lscp_mutex_destroy(pClient->mutex);          lscp_mutex_destroy(pClient->mutex);
282          free(pClient);          free(pClient);
283          return NULL;          return NULL;
# Line 320  lscp_status_t lscp_client_join ( lscp_cl Line 302  lscp_status_t lscp_client_join ( lscp_cl
302      fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);      fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);
303  #endif  #endif
304    
305  //  lscp_socket_agent_join(&(pClient->udp));  //  lscp_socket_agent_join(&(pClient->evt));
306      lscp_socket_agent_join(&(pClient->tcp));      lscp_socket_agent_join(&(pClient->cmd));
307    
308      return LSCP_OK;      return LSCP_OK;
309  }  }
# Line 343  lscp_status_t lscp_client_destroy ( lscp Line 325  lscp_status_t lscp_client_destroy ( lscp
325      fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);      fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);
326  #endif  #endif
327    
328      // Free session-id, if any.      // Lock this section up.
329        lscp_mutex_lock(pClient->mutex);
330        
331       // Free session-id, if any.
332      if (pClient->sessid)      if (pClient->sessid)
333          free(pClient->sessid);          free(pClient->sessid);
334      pClient->sessid = NULL;      pClient->sessid = NULL;
# Line 364  lscp_status_t lscp_client_destroy ( lscp Line 349  lscp_status_t lscp_client_destroy ( lscp
349      pClient->midi_drivers = NULL;      pClient->midi_drivers = NULL;
350      pClient->engines = NULL;      pClient->engines = NULL;
351      // Free result error stuff.      // Free result error stuff.
352      _lscp_client_set_result(pClient, NULL, 0);      lscp_client_set_result(pClient, NULL, 0);
353      // Frre stream usage stuff.      // Frre stream usage stuff.
354      if (pClient->buffer_fill)      if (pClient->buffer_fill)
355          free(pClient->buffer_fill);          free(pClient->buffer_fill);
# Line 373  lscp_status_t lscp_client_destroy ( lscp Line 358  lscp_status_t lscp_client_destroy ( lscp
358      pClient->iTimeout = 0;      pClient->iTimeout = 0;
359    
360      // Free socket agents.      // Free socket agents.
361      lscp_socket_agent_free(&(pClient->udp));      lscp_socket_agent_free(&(pClient->evt));
362      lscp_socket_agent_free(&(pClient->tcp));      lscp_socket_agent_free(&(pClient->cmd));
363    
364      // Last but not least, free good ol'transaction mutex.      // Last but not least, free good ol'transaction mutex.
365        lscp_mutex_unlock(pClient->mutex);
366      lscp_mutex_destroy(pClient->mutex);      lscp_mutex_destroy(pClient->mutex);
367    
368      free(pClient);      free(pClient);
# Line 424  int lscp_client_get_timeout ( lscp_clien Line 410  int lscp_client_get_timeout ( lscp_clien
410  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
411  // Client common protocol functions.  // Client common protocol functions.
412    
   
413  /**  /**
414   *  Submit a command query line string to the server. The query string   *  Submit a command query line string to the server. The query string
415   *  must be cr/lf and null terminated. Besides the return code, the   *  must be cr/lf and null terminated. Besides the return code, the
# Line 440  int lscp_client_get_timeout ( lscp_clien Line 425  int lscp_client_get_timeout ( lscp_clien
425   */   */
426  lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )  lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )
427  {  {
428      fd_set fds;                         // File descriptor list for select().      lscp_status_t ret;
429      int    fd, fdmax;                   // Maximum file descriptor number.      
     struct timeval tv;                  // For specifying a timeout value.  
     int    iSelect;                     // Holds select return status.  
     int    iTimeout;  
     int    cchQuery;  
     char   achResult[LSCP_BUFSIZ];  
     int    cchResult;  
     const  char *pszSeps = ":[]";  
     char  *pszResult;  
     char  *pszToken;  
     char  *pch;  
     int    iErrno;  
   
     lscp_status_t ret = LSCP_FAILED;  
   
     if (pClient == NULL)  
         return ret;  
   
430      // Lock this section up.      // Lock this section up.
431      lscp_mutex_lock(pClient->mutex);      lscp_mutex_lock(pClient->mutex);
432    
433      pszResult = NULL;      // Just make the now guarded call.
434      iErrno = -1;      ret = lscp_client_call(pClient, pszQuery);
435        
436      // Send data, and then, wait for the result...      // Unlock this section down.
     cchQuery = strlen(pszQuery);  
     if (send(pClient->tcp.sock, pszQuery, cchQuery, 0) < cchQuery) {  
         lscp_socket_perror("lscp_client_query: send");  
         pszResult = "Failure during send operation";  
         _lscp_client_set_result(pClient, pszResult, iErrno);  
         lscp_mutex_unlock(pClient->mutex);  
         return ret;  
     }  
   
     // Prepare for waiting on select...  
     fd = (int) pClient->tcp.sock;  
     FD_ZERO(&fds);  
     FD_SET((unsigned int) fd, &fds);  
     fdmax = fd;  
   
     // Use the timeout select feature...  
     iTimeout = pClient->iTimeout;  
     if (iTimeout > 1000) {  
         tv.tv_sec = iTimeout / 1000;  
         iTimeout -= tv.tv_sec * 1000;  
     }  
     else tv.tv_sec = 0;  
     tv.tv_usec = iTimeout * 1000;  
   
     // Wait for event...  
     iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);  
     if (iSelect > 0 && FD_ISSET(fd, &fds)) {  
         // May recv now...  
         cchResult = recv(pClient->tcp.sock, achResult, sizeof(achResult), 0);  
         if (cchResult > 0) {  
             // Assume early success.  
             ret = LSCP_OK;  
             // Always force the result to be null terminated (and trim trailing CRLFs)!  
             while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))  
                 cchResult--;  
             achResult[cchResult] = (char) 0;  
             // Check if the response it's an error or warning message.  
             if (strncasecmp(achResult, "WRN:", 4) == 0)  
                 ret = LSCP_WARNING;  
             else if (strncasecmp(achResult, "ERR:", 4) == 0)  
                 ret = LSCP_ERROR;  
             // So we got a result...  
             if (ret == LSCP_OK) {  
                 // Reset errno in case of success.  
                 iErrno = 0;  
                 // Is it a special successful response?  
                 if (strncasecmp(achResult, "OK[", 3) == 0) {  
                     // Parse the OK message, get the return string under brackets...  
                     pszToken = lscp_strtok(achResult, pszSeps, &(pch));  
                     if (pszToken)  
                         pszResult = lscp_strtok(NULL, pszSeps, &(pch));  
                 }  
                 else pszResult = achResult;  
                 // The result string is now set to the command response, if any.  
             } else {  
                 // Parse the error/warning message, skip first colon...  
                 pszToken = lscp_strtok(achResult, pszSeps, &(pch));  
                 if (pszToken) {  
                     // Get the error number...  
                     pszToken = lscp_strtok(NULL, pszSeps, &(pch));  
                     if (pszToken) {  
                         iErrno = atoi(pszToken);  
                         // And make the message text our final result.  
                         pszResult = lscp_strtok(NULL, pszSeps, &(pch));  
                     }  
                 }  
                 // The result string is set to the error/warning message text.  
             }  
         }  
         else if (cchResult == 0) {  
             // Fake a result message.  
             ret = LSCP_QUIT;  
             pszResult = "Server terminated the connection";  
             iErrno = (int) ret;  
         } else {  
             // What's down?  
             lscp_socket_perror("lscp_client_query: recv");  
             pszResult = "Failure during receive operation";  
         }  
     }   // Check if select has timed out.  
     else if (iSelect == 0) {  
         // Fake a result message.  
         ret = LSCP_TIMEOUT;  
         pszResult = "Timeout during receive operation";  
         iErrno = (int) ret;  
    }  
     else lscp_socket_perror("lscp_client_query: select");  
   
     // Make the result official...  
     _lscp_client_set_result(pClient, pszResult, iErrno);  
   
     // Can go on with it...  
437      lscp_mutex_unlock(pClient->mutex);      lscp_mutex_unlock(pClient->mutex);
438        
439      return ret;      return ret;
440  }  }
441    
   
442  /**  /**
443   *  Get the last received result string. In case of error or warning,   *  Get the last received result string. In case of error or warning,
444   *  this is the text of the error or warning message issued.   *  this is the text of the error or warning message issued.
# Line 622  lscp_status_t lscp_client_subscribe ( ls Line 497  lscp_status_t lscp_client_subscribe ( ls
497      if (pClient == NULL || pClient->sessid)      if (pClient == NULL || pClient->sessid)
498          return LSCP_FAILED;          return LSCP_FAILED;
499    
500      sprintf(szQuery, "SUBSCRIBE NOTIFICATION %d\r\n", ntohs(pClient->udp.addr.sin_port));      // Lock this section up.
501      ret = lscp_client_query(pClient, szQuery);      lscp_mutex_lock(pClient->mutex);
502        
503        sprintf(szQuery, "SUBSCRIBE NOTIFICATION %d\r\n", ntohs(pClient->evt.addr.sin_port));
504        ret = lscp_client_call(pClient, szQuery);
505      if (ret == LSCP_OK) {      if (ret == LSCP_OK) {
506          pszResult = lscp_client_get_result(pClient);          pszResult = lscp_client_get_result(pClient);
507  #ifdef DEBUG  #ifdef DEBUG
# Line 638  lscp_status_t lscp_client_subscribe ( ls Line 516  lscp_status_t lscp_client_subscribe ( ls
516          }          }
517      }      }
518    
519        // Unlock this section down.
520        lscp_mutex_unlock(pClient->mutex);
521    
522      return ret;      return ret;
523  }  }
524    
# Line 660  lscp_status_t lscp_client_unsubscribe ( Line 541  lscp_status_t lscp_client_unsubscribe (
541      if (pClient->sessid == NULL)      if (pClient->sessid == NULL)
542          return LSCP_FAILED;          return LSCP_FAILED;
543    
544        // Lock this section up.
545        lscp_mutex_lock(pClient->mutex);
546    
547      sprintf(szQuery, "UNSUBSCRIBE NOTIFICATION %s\n\n", pClient->sessid);      sprintf(szQuery, "UNSUBSCRIBE NOTIFICATION %s\n\n", pClient->sessid);
548      ret = lscp_client_query(pClient, szQuery);      ret = lscp_client_call(pClient, szQuery);
549      if (ret == LSCP_OK) {      if (ret == LSCP_OK) {
550  #ifdef DEBUG  #ifdef DEBUG
551          fprintf(stderr, "lscp_client_unsubscribe: %s\n", lscp_client_get_result(pClient));          fprintf(stderr, "lscp_client_unsubscribe: %s\n", lscp_client_get_result(pClient));
# Line 671  lscp_status_t lscp_client_unsubscribe ( Line 555  lscp_status_t lscp_client_unsubscribe (
555          pClient->sessid = NULL;          pClient->sessid = NULL;
556      }      }
557    
558        // Unlock this section down.
559        lscp_mutex_unlock(pClient->mutex);
560    
561      return ret;      return ret;
562  }  }
563    
# Line 735  lscp_status_t lscp_load_engine ( lscp_cl Line 622  lscp_status_t lscp_load_engine ( lscp_cl
622  int lscp_get_channels ( lscp_client_t *pClient )  int lscp_get_channels ( lscp_client_t *pClient )
623  {  {
624      int iChannels = -1;      int iChannels = -1;
625      if (lscp_client_query(pClient, "GET CHANNELS\r\n") == LSCP_OK)  
626        // Lock this section up.
627        lscp_mutex_lock(pClient->mutex);
628    
629        if (lscp_client_call(pClient, "GET CHANNELS\r\n") == LSCP_OK)
630          iChannels = atoi(lscp_client_get_result(pClient));          iChannels = atoi(lscp_client_get_result(pClient));
631    
632        // Unlock this section doen.
633        lscp_mutex_unlock(pClient->mutex);
634    
635      return iChannels;      return iChannels;
636  }  }
637    
# Line 757  int *lscp_list_channels ( lscp_client_t Line 652  int *lscp_list_channels ( lscp_client_t
652      if (pClient == NULL)      if (pClient == NULL)
653          return NULL;          return NULL;
654                    
655        // Lock this section up.
656        lscp_mutex_lock(pClient->mutex);
657    
658      if (pClient->channels) {      if (pClient->channels) {
659          lscp_isplit_destroy(pClient->channels);          lscp_isplit_destroy(pClient->channels);
660          pClient->channels = NULL;          pClient->channels = NULL;
661      }      }
662    
663      if (lscp_client_query(pClient, "LIST CHANNELS\r\n") == LSCP_OK)      if (lscp_client_call(pClient, "LIST CHANNELS\r\n") == LSCP_OK)
664          pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);          pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
665    
666        // Unlock this section down.
667        lscp_mutex_unlock(pClient->mutex);
668    
669      return pClient->channels;      return pClient->channels;
670  }  }
671    
# Line 781  int *lscp_list_channels ( lscp_client_t Line 682  int *lscp_list_channels ( lscp_client_t
682  int lscp_add_channel ( lscp_client_t *pClient )  int lscp_add_channel ( lscp_client_t *pClient )
683  {  {
684      int iSamplerChannel = -1;      int iSamplerChannel = -1;
685      if (lscp_client_query(pClient, "ADD CHANNEL\r\n") == LSCP_OK)  
686        // Lock this section up.
687        lscp_mutex_lock(pClient->mutex);
688    
689        if (lscp_client_call(pClient, "ADD CHANNEL\r\n") == LSCP_OK)
690          iSamplerChannel = atoi(lscp_client_get_result(pClient));          iSamplerChannel = atoi(lscp_client_get_result(pClient));
691            
692        // Unlock this section down.
693        lscp_mutex_unlock(pClient->mutex);
694    
695      return iSamplerChannel;      return iSamplerChannel;
696  }  }
697    
# Line 821  const char **lscp_get_available_engines Line 730  const char **lscp_get_available_engines
730  {  {
731      const char *pszSeps = ",";      const char *pszSeps = ",";
732    
733        // Lock this section up.
734        lscp_mutex_lock(pClient->mutex);
735    
736      if (pClient->engines) {      if (pClient->engines) {
737          lscp_szsplit_destroy(pClient->engines);          lscp_szsplit_destroy(pClient->engines);
738          pClient->engines = NULL;          pClient->engines = NULL;
739      }      }
740    
741      if (lscp_client_query(pClient, "GET AVAILABLE_ENGINES\r\n") == LSCP_OK)      if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n") == LSCP_OK)
742          pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);          pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
743    
744        // Unlock this section down.
745        lscp_mutex_unlock(pClient->mutex);
746    
747      return (const char **) pClient->engines;      return (const char **) pClient->engines;
748  }  }
749    
# Line 856  lscp_engine_info_t *lscp_get_engine_info Line 771  lscp_engine_info_t *lscp_get_engine_info
771      if (pszEngineName == NULL)      if (pszEngineName == NULL)
772          return NULL;          return NULL;
773    
774        // Lock this section up.
775        lscp_mutex_lock(pClient->mutex);
776    
777      pEngineInfo = &(pClient->engine_info);      pEngineInfo = &(pClient->engine_info);
778      lscp_engine_info_reset(pEngineInfo);      lscp_engine_info_reset(pEngineInfo);
779    
780      sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);      sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
781      if (lscp_client_query(pClient, szQuery) != LSCP_OK)      if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
782          return NULL;          pszResult = lscp_client_get_result(pClient);
783            pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
784      pszResult = lscp_client_get_result(pClient);          while (pszToken) {
785      pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));              if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
786      while (pszToken) {                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
787          if (strcasecmp(pszToken, "DESCRIPTION") == 0) {                  if (pszToken)
788              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pEngineInfo->description = lscp_unquote(&pszToken, 1);
789              if (pszToken)              }
790                  pEngineInfo->description = lscp_unquote(&pszToken, 1);              else if (strcasecmp(pszToken, "VERSION") == 0) {
791          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
792          else if (strcasecmp(pszToken, "VERSION") == 0) {                  if (pszToken)
793              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pEngineInfo->version = lscp_unquote(&pszToken, 1);
794              if (pszToken)              }
795                  pEngineInfo->version = lscp_unquote(&pszToken, 1);              pszToken = lscp_strtok(NULL, pszSeps, &(pch));
796          }          }
         pszToken = lscp_strtok(NULL, pszSeps, &(pch));  
797      }      }
798        else pEngineInfo = NULL;
799        
800        // Unlock this section down.
801        lscp_mutex_unlock(pClient->mutex);
802    
803      return pEngineInfo;      return pEngineInfo;
804  }  }
# Line 906  lscp_channel_info_t *lscp_get_channel_in Line 827  lscp_channel_info_t *lscp_get_channel_in
827      if (iSamplerChannel < 0)      if (iSamplerChannel < 0)
828          return NULL;          return NULL;
829    
830        // Lock this section up.
831        lscp_mutex_lock(pClient->mutex);
832        
833      pChannelInfo = &(pClient->channel_info);      pChannelInfo = &(pClient->channel_info);
834      lscp_channel_info_reset(pChannelInfo);      lscp_channel_info_reset(pChannelInfo);
835    
836      sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);      sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
837      if (lscp_client_query(pClient, szQuery) != LSCP_OK)      if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
838          return NULL;          pszResult = lscp_client_get_result(pClient);
839            pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
840      pszResult = lscp_client_get_result(pClient);          while (pszToken) {
841      pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));              if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
842      while (pszToken) {                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
843          if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {                  if (pszToken)
844              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->engine_name = lscp_unquote(&pszToken, 1);
845              if (pszToken)              }
846                  pChannelInfo->engine_name = lscp_unquote(&pszToken, 1);              else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
847          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
848          else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {                  if (pszToken)
849              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
850              if (pszToken)              }
851                  pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));              else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
852          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
853          else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {                  if (pszToken)
854              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
855              if (pszToken)              }
856                  pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));              else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
857          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
858          else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {                  if (pszToken)
859              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");
860              if (pszToken)              }
861                  pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");              else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
862          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
863          else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {                  if (pszToken)
864              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->instrument_file = lscp_unquote(&pszToken, 1);
865              if (pszToken)              }
866                  pChannelInfo->instrument_file = lscp_unquote(&pszToken, 1);              else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
867          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
868          else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {                  if (pszToken)
869              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
870              if (pszToken)              }
871                  pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));              else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
872          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
873          else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {                  if (pszToken)
874              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
875              if (pszToken)              }
876                  pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));              else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
877          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
878          else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {                  if (pszToken)
879              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
880              if (pszToken)              }
881                  pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));              else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
882          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
883          else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {                  if (pszToken)
884              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
885              if (pszToken)              }
886                  pChannelInfo->midi_channel = atoi(lscp_ltrim(pszToken));              else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
887          }                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
888          else if (strcasecmp(pszToken, "VOLUME") == 0) {                  if (pszToken)
889              pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                      pChannelInfo->midi_channel = atoi(lscp_ltrim(pszToken));
890              if (pszToken)              }
891                  pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));              else if (strcasecmp(pszToken, "VOLUME") == 0) {
892                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
893                    if (pszToken)
894                        pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));
895                }
896                pszToken = lscp_strtok(NULL, pszSeps, &(pch));
897          }          }
         pszToken = lscp_strtok(NULL, pszSeps, &(pch));  
898      }      }
899        else pChannelInfo = NULL;
900        
901        // Unlock this section up.
902        lscp_mutex_unlock(pClient->mutex);
903    
904      return pChannelInfo;      return pChannelInfo;
905  }  }
# Line 990  int lscp_get_channel_voice_count ( lscp_ Line 922  int lscp_get_channel_voice_count ( lscp_
922      if (iSamplerChannel < 0)      if (iSamplerChannel < 0)
923          return iVoiceCount;          return iVoiceCount;
924    
925        // Lock this section up.
926        lscp_mutex_lock(pClient->mutex);
927    
928      sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);      sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
929      if (lscp_client_query(pClient, szQuery) == LSCP_OK)      if (lscp_client_call(pClient, szQuery) == LSCP_OK)
930          iVoiceCount = atoi(lscp_client_get_result(pClient));          iVoiceCount = atoi(lscp_client_get_result(pClient));
931    
932        // Unlock this section down.
933        lscp_mutex_unlock(pClient->mutex);
934    
935      return iVoiceCount;      return iVoiceCount;
936  }  }
937    
# Line 1012  int lscp_get_channel_stream_count ( lscp Line 950  int lscp_get_channel_stream_count ( lscp
950      if (iSamplerChannel < 0)      if (iSamplerChannel < 0)
951          return iStreamCount;          return iStreamCount;
952    
953        // Lock this section up.
954        lscp_mutex_lock(pClient->mutex);
955    
956      sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);      sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
957      if (lscp_client_query(pClient, szQuery) == LSCP_OK)      if (lscp_client_call(pClient, szQuery) == LSCP_OK)
958          iStreamCount = atoi(lscp_client_get_result(pClient));          iStreamCount = atoi(lscp_client_get_result(pClient));
959    
960        // Unlock this section down.
961        lscp_mutex_unlock(pClient->mutex);
962    
963      return iStreamCount;      return iStreamCount;
964  }  }
965    
# Line 1046  lscp_buffer_fill_t *lscp_get_channel_buf Line 990  lscp_buffer_fill_t *lscp_get_channel_buf
990      char *pch;      char *pch;
991      int   iStream;      int   iStream;
992    
993        // Retrieve a channel stream estimation.
994      iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);      iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
995        if (pClient->iStreamCount < 0)
996            return NULL;
997    
998        // Lock this section up.
999        lscp_mutex_lock(pClient->mutex);
1000    
1001        // Check if we need to reallocate the stream usage array.
1002      if (pClient->iStreamCount != iStreamCount) {      if (pClient->iStreamCount != iStreamCount) {
1003          if (pClient->buffer_fill)          if (pClient->buffer_fill)
1004              free(pClient->buffer_fill);              free(pClient->buffer_fill);
# Line 1057  lscp_buffer_fill_t *lscp_get_channel_buf Line 1009  lscp_buffer_fill_t *lscp_get_channel_buf
1009          pClient->iStreamCount = iStreamCount;          pClient->iStreamCount = iStreamCount;
1010      }      }
1011    
     if (pClient->iStreamCount < 1)  
         return NULL;  
   
     iStream = 0;  
     pBufferFill = pClient->buffer_fill;  
   
1012      // Get buffer fill usage...      // Get buffer fill usage...
1013      sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);      pBufferFill = pClient->buffer_fill;
1014      if (lscp_client_query(pClient, szQuery) == LSCP_OK) {      if (pBufferFill && iStreamCount > 0) {
1015          pszResult = lscp_client_get_result(pClient);          iStream = 0;
1016          pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));          pBufferFill = pClient->buffer_fill;
1017          while (pszToken && iStream < pClient->iStreamCount) {          sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1018              if (*pszToken) {          if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
1019                  pBufferFill[iStream].stream_id = atol(pszToken);              pszResult = lscp_client_get_result(pClient);
1020                pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1021                while (pszToken && iStream < pClient->iStreamCount) {
1022                    if (*pszToken) {
1023                        pBufferFill[iStream].stream_id = atol(pszToken);
1024                        pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1025                        if (pszToken == NULL)
1026                            break;
1027                        pBufferFill[iStream].stream_usage = atol(pszToken);
1028                        iStream++;
1029                    }
1030                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));
                 if (pszToken == NULL)  
                     break;  
                 pBufferFill[iStream].stream_usage = atol(pszToken);  
                 iStream++;  
1031              }              }
1032              pszToken = lscp_strtok(NULL, pszSeps, &(pch));          }   // Reset the usage, whatever it was before.
1033          }          else while (iStream < pClient->iStreamCount)
1034      }   // Reset the usage, whatever it was before.              pBufferFill[iStream++].stream_usage = 0;
1035      else while (iStream < pClient->iStreamCount)      }
1036          pBufferFill[iStream++].stream_usage = 0;      
1037        // Unlock this section down.
1038        lscp_mutex_unlock(pClient->mutex);
1039    
1040      return pBufferFill;      return pBufferFill;
1041  }  }

Legend:
Removed from v.125  
changed lines
  Added in v.132

  ViewVC Help
Powered by ViewVC