| @@ -1915,3 +1915,66 @@ EXPORT void jack_session_event_free(jack_session_event_t* ev) | |||
| free(ev); | |||
| } | |||
| EXPORT char *jack_get_uuid_for_client_name( jack_client_t *ext_client, const char *client_name ) | |||
| { | |||
| #ifdef __CLIENTDEBUG__ | |||
| JackGlobals::CheckContext("jack_get_uuid_for_client_name"); | |||
| #endif | |||
| JackClient* client = (JackClient*)ext_client; | |||
| jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client); | |||
| if (client == NULL) { | |||
| jack_error("jack_get_uuid_for_client_name called with a NULL client"); | |||
| return NULL; | |||
| } else { | |||
| return client->GetUUIDForClientName(client_name); | |||
| } | |||
| } | |||
| EXPORT char *jack_get_client_name_by_uuid( jack_client_t *ext_client, const char *client_uuid ) | |||
| { | |||
| #ifdef __CLIENTDEBUG__ | |||
| JackGlobals::CheckContext("jack_get_client_name_by_uuid"); | |||
| #endif | |||
| JackClient* client = (JackClient*)ext_client; | |||
| jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client); | |||
| if (client == NULL) { | |||
| jack_error("jack_get_client_name_by_uuid called with a NULL client"); | |||
| return NULL; | |||
| } else { | |||
| return client->GetClientNameForUUID(client_uuid); | |||
| } | |||
| } | |||
| EXPORT int jack_reserve_client_name( jack_client_t *ext_client, const char *name, const char *uuid ) | |||
| { | |||
| #ifdef __CLIENTDEBUG__ | |||
| JackGlobals::CheckContext("jack_reserve_client_name"); | |||
| #endif | |||
| JackClient* client = (JackClient*)ext_client; | |||
| jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client); | |||
| if (client == NULL) { | |||
| jack_error("jack_reserve_client_name called with a NULL client"); | |||
| return -1; | |||
| } else { | |||
| return client->ReserveClientName(name, uuid); | |||
| } | |||
| } | |||
| EXPORT void jack_session_commands_free( jack_session_command_t *cmds ) | |||
| { | |||
| int i=0; | |||
| while(1) { | |||
| if (cmds[i].client_name) | |||
| free ((char *)cmds[i].client_name); | |||
| if (cmds[i].command) | |||
| free ((char *)cmds[i].command); | |||
| if (cmds[i].uuid) | |||
| free ((char *)cmds[i].uuid); | |||
| else | |||
| break; | |||
| i += 1; | |||
| } | |||
| free(cmds); | |||
| } | |||
| @@ -133,6 +133,15 @@ class JackClientChannelInterface | |||
| virtual void SessionReply(int refnum, int *result) | |||
| {} | |||
| virtual void GetUUIDForClientName( int refnum, const char *client_name, char *uuid_res, int *result ) | |||
| {} | |||
| virtual void GetClientNameForUUID( int refnum, const char *uuid, char *name_res, int *result ) | |||
| {} | |||
| virtual void ReserveClientName( int refnum, const char *client_name, const char *uuid, int *result ) | |||
| {} | |||
| virtual bool IsChannelThread() | |||
| { return false; } | |||
| }; | |||
| @@ -1109,5 +1109,36 @@ int JackClient::SessionReply( jack_session_event_t *ev ) | |||
| return res; | |||
| } | |||
| char* JackClient::GetUUIDForClientName(const char* client_name) | |||
| { | |||
| char uuid_res[JACK_CLIENT_NAME_SIZE + 1]; | |||
| int result = -1; | |||
| fChannel->GetUUIDForClientName( GetClientControl()->fRefNum, client_name, uuid_res, &result); | |||
| if(result) | |||
| return NULL; | |||
| return strdup(uuid_res); | |||
| } | |||
| char* JackClient::GetClientNameForUUID(const char* uuid) | |||
| { | |||
| char name_res[JACK_CLIENT_NAME_SIZE + 1]; | |||
| int result = -1; | |||
| fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result); | |||
| if(result) | |||
| return NULL; | |||
| return strdup(name_res); | |||
| } | |||
| int JackClient::ReserveClientName(const char *name, const char* uuid) | |||
| { | |||
| int result = -1; | |||
| fChannel->ReserveClientName( GetClientControl()->fRefNum, name, uuid, &result); | |||
| return result; | |||
| } | |||
| } // end of namespace | |||
| @@ -193,6 +193,9 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||
| // Session api | |||
| virtual jack_session_command_t *SessionNotify(const char *target, jack_session_event_type_t type, const char *path); | |||
| virtual int SessionReply(jack_session_event_t *ev); | |||
| char* GetUUIDForClientName(const char* client_name); | |||
| char* GetClientNameForUUID(const char* uuid); | |||
| int ReserveClientName(const char *name, const char* uuid); | |||
| // JackRunnableInterface interface | |||
| bool Init(); | |||
| @@ -872,6 +872,12 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even | |||
| return; | |||
| } | |||
| for (int i = 0; i < CLIENT_NUM; i++) { | |||
| JackClientInterface* client = fClientTable[i]; | |||
| if (client && (client->GetClientControl()->fSessionID < 0)) { | |||
| client->GetClientControl()->fSessionID = GetNewUUID(); | |||
| } | |||
| } | |||
| fSessionResult = new JackSessionNotifyResult(); | |||
| for (int i = 0; i < CLIENT_NUM; i++) { | |||
| @@ -932,5 +938,59 @@ void JackEngine::SessionReply(int refnum) | |||
| } | |||
| } | |||
| void JackEngine::GetUUIDForClientName(const char *client_name, char *uuid_res, int *result) | |||
| { | |||
| for (int i = 0; i < CLIENT_NUM; i++) { | |||
| JackClientInterface* client = fClientTable[i]; | |||
| if (client && (strcmp(client_name, client->GetClientControl()->fName)==0)) { | |||
| snprintf(uuid_res, 32, "%d", client->GetClientControl()->fSessionID); | |||
| *result = 0; | |||
| return; | |||
| } | |||
| } | |||
| // did not find name. | |||
| *result = -1; | |||
| return; | |||
| } | |||
| void JackEngine::GetClientNameForUUID(const char *uuid, char *name_res, int *result) | |||
| { | |||
| jack_log( "want uuid %s", uuid ); | |||
| for (int i = 0; i < CLIENT_NUM; i++) { | |||
| JackClientInterface* client = fClientTable[i]; | |||
| if (!client) | |||
| continue; | |||
| char uuid_buf[33]; | |||
| snprintf(uuid_buf, 32, "%d", client->GetClientControl()->fSessionID); | |||
| jack_log( "check uuid %s", uuid_buf ); | |||
| if (strcmp(uuid,uuid_buf) == 0) { | |||
| strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); | |||
| *result = 0; | |||
| jack_log( "found name\n" ); | |||
| return; | |||
| } | |||
| } | |||
| // did not find uuid. | |||
| *result = -1; | |||
| return; | |||
| } | |||
| void JackEngine::ReserveClientName(const char *name, const char *uuid, int *result) | |||
| { | |||
| if (ClientCheckName(name)) | |||
| { | |||
| *result = -1; | |||
| return; | |||
| } | |||
| EnsureUUID(atoi(uuid)); | |||
| fReservationMap[atoi(uuid)] = name; | |||
| } | |||
| } // end of namespace | |||
| @@ -55,6 +55,8 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||
| int fSessionPendingReplies; | |||
| JackChannelTransaction *fSessionTransaction; | |||
| JackSessionNotifyResult *fSessionResult; | |||
| std::map<int,std::string> fReservationMap; | |||
| int fMaxUUID; | |||
| int ClientCloseAux(int refnum, JackClientInterface* client, bool wait); | |||
| @@ -139,6 +141,11 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||
| void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); | |||
| void SessionReply( int refnum ); | |||
| int GetNewUUID(); | |||
| void EnsureUUID(int uuid); | |||
| void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result); | |||
| void GetClientNameForUUID(const char *uuid, char *name_res, int *result); | |||
| void ReserveClientName(const char *name, const char *uuid, int *result); | |||
| }; | |||
| @@ -323,6 +323,27 @@ class SERVER_EXPORT JackLockedEngine | |||
| CATCH_EXCEPTION | |||
| } | |||
| void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result) | |||
| { | |||
| TRY_CALL | |||
| JackLock lock(&fEngine); | |||
| fEngine.GetUUIDForClientName(client_name, uuid_res, result); | |||
| CATCH_EXCEPTION | |||
| } | |||
| void GetClientNameForUUID(const char *uuid, char *name_res, int *result) | |||
| { | |||
| TRY_CALL | |||
| JackLock lock(&fEngine); | |||
| fEngine.GetClientNameForUUID(uuid, name_res, result); | |||
| CATCH_EXCEPTION | |||
| } | |||
| void ReserveClientName(const char *name, const char *uuid, int *result) | |||
| { | |||
| TRY_CALL | |||
| JackLock lock(&fEngine); | |||
| fEngine.ReserveClientName(name, uuid, result); | |||
| CATCH_EXCEPTION | |||
| } | |||
| }; | |||
| } // end of namespace | |||
| @@ -70,7 +70,8 @@ struct JackRequest | |||
| kSessionNotify = 33, | |||
| kSessionReply = 34, | |||
| kGetClientByUUID = 35, | |||
| kReserveClientName = 36 | |||
| kReserveClientName = 36, | |||
| kGetUUIDByClient = 37 | |||
| }; | |||
| RequestType fType; | |||
| @@ -1211,6 +1212,156 @@ struct JackSessionReplyRequest : public JackRequest | |||
| } POST_PACKED_STRUCTURE; | |||
| struct JackClientNameResult : public JackResult | |||
| { | |||
| char fName[JACK_CLIENT_NAME_SIZE + 1]; | |||
| JackClientNameResult(): JackResult() | |||
| {} | |||
| JackClientNameResult(int32_t result, const char* name) | |||
| : JackResult(result) | |||
| { | |||
| snprintf(fName, sizeof(fName), "%s", name); | |||
| } | |||
| int Read(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackResult::Read(trans)); | |||
| CheckRes(trans->Read(&fName, sizeof(fName))); | |||
| return 0; | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackResult::Write(trans)); | |||
| CheckRes(trans->Write(&fName, sizeof(fName))); | |||
| return 0; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| struct JackUUIDResult : public JackResult | |||
| { | |||
| char fUUID[32 + 1]; | |||
| JackUUIDResult(): JackResult() | |||
| {} | |||
| JackUUIDResult(int32_t result, const char* uuid) | |||
| : JackResult(result) | |||
| { | |||
| snprintf(fUUID, sizeof(fUUID), "%s", uuid); | |||
| } | |||
| int Read(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackResult::Read(trans)); | |||
| CheckRes(trans->Read(&fUUID, sizeof(fUUID))); | |||
| return 0; | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackResult::Write(trans)); | |||
| CheckRes(trans->Write(&fUUID, sizeof(fUUID))); | |||
| return 0; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| struct JackGetUUIDRequest : public JackRequest | |||
| { | |||
| char fName[JACK_CLIENT_NAME_SIZE + 1]; | |||
| JackGetUUIDRequest() | |||
| {} | |||
| JackGetUUIDRequest(const char* client_name) | |||
| : JackRequest(JackRequest::kGetUUIDByClient) | |||
| { | |||
| strncpy(fName, client_name, sizeof(fName)); | |||
| } | |||
| int Read(JackChannelTransaction* trans) | |||
| { | |||
| //CheckRes(JackRequest::Read(trans)); | |||
| CheckRes(trans->Read(&fName, sizeof(fName))); | |||
| return 0; | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackRequest::Write(trans)); | |||
| CheckRes(trans->Write(&fName, sizeof(fName))); | |||
| return 0; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| struct JackGetClientNameRequest : public JackRequest | |||
| { | |||
| char fUUID[32 + 1]; | |||
| JackGetClientNameRequest() | |||
| {} | |||
| JackGetClientNameRequest(const char* uuid) | |||
| : JackRequest(JackRequest::kGetClientByUUID) | |||
| { | |||
| strncpy(fUUID, uuid, sizeof(fUUID)); | |||
| } | |||
| int Read(JackChannelTransaction* trans) | |||
| { | |||
| //CheckRes(JackRequest::Read(trans)); | |||
| CheckRes(trans->Read(&fUUID, sizeof(fUUID))); | |||
| return 0; | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackRequest::Write(trans)); | |||
| CheckRes(trans->Write(&fUUID, sizeof(fUUID))); | |||
| return 0; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| struct JackReserveNameRequest : public JackRequest | |||
| { | |||
| int fRefNum; | |||
| char fName[JACK_CLIENT_NAME_SIZE + 1]; | |||
| char fUUID[32 + 1]; | |||
| JackReserveNameRequest() | |||
| {} | |||
| JackReserveNameRequest(int refnum, const char *name, const char* uuid) | |||
| : JackRequest(JackRequest::kReserveClientName), fRefNum(refnum) | |||
| { | |||
| strncpy(fName, name, sizeof(fName)); | |||
| strncpy(fUUID, uuid, sizeof(fUUID)); | |||
| } | |||
| int Read(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(trans->Read(&fUUID, sizeof(fUUID))); | |||
| CheckRes(trans->Read(&fName, sizeof(fName))); | |||
| CheckRes(trans->Read(&fRefNum, sizeof(fRefNum))); | |||
| return 0; | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackRequest::Write(trans)); | |||
| CheckRes(trans->Write(&fUUID, sizeof(fUUID))); | |||
| CheckRes(trans->Write(&fName, sizeof(fName))); | |||
| CheckRes(trans->Write(&fRefNum, sizeof(fRefNum))); | |||
| return 0; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| /*! | |||
| \brief ClientNotification. | |||
| */ | |||