| @@ -1915,3 +1915,66 @@ EXPORT void jack_session_event_free(jack_session_event_t* ev) | |||||
| free(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 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() | virtual bool IsChannelThread() | ||||
| { return false; } | { return false; } | ||||
| }; | }; | ||||
| @@ -1109,5 +1109,36 @@ int JackClient::SessionReply( jack_session_event_t *ev ) | |||||
| return res; | 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 | } // end of namespace | ||||
| @@ -193,6 +193,9 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||||
| // Session api | // Session api | ||||
| virtual jack_session_command_t *SessionNotify(const char *target, jack_session_event_type_t type, const char *path); | 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); | 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 | // JackRunnableInterface interface | ||||
| bool Init(); | bool Init(); | ||||
| @@ -872,6 +872,12 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even | |||||
| return; | 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(); | fSessionResult = new JackSessionNotifyResult(); | ||||
| for (int i = 0; i < CLIENT_NUM; i++) { | 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 | } // end of namespace | ||||
| @@ -55,6 +55,8 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||||
| int fSessionPendingReplies; | int fSessionPendingReplies; | ||||
| JackChannelTransaction *fSessionTransaction; | JackChannelTransaction *fSessionTransaction; | ||||
| JackSessionNotifyResult *fSessionResult; | JackSessionNotifyResult *fSessionResult; | ||||
| std::map<int,std::string> fReservationMap; | |||||
| int fMaxUUID; | |||||
| int ClientCloseAux(int refnum, JackClientInterface* client, bool wait); | 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 SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); | ||||
| void SessionReply( int refnum ); | 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 | 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 | } // end of namespace | ||||
| @@ -70,7 +70,8 @@ struct JackRequest | |||||
| kSessionNotify = 33, | kSessionNotify = 33, | ||||
| kSessionReply = 34, | kSessionReply = 34, | ||||
| kGetClientByUUID = 35, | kGetClientByUUID = 35, | ||||
| kReserveClientName = 36 | |||||
| kReserveClientName = 36, | |||||
| kGetUUIDByClient = 37 | |||||
| }; | }; | ||||
| RequestType fType; | RequestType fType; | ||||
| @@ -1211,6 +1212,156 @@ struct JackSessionReplyRequest : public JackRequest | |||||
| } POST_PACKED_STRUCTURE; | } 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. | \brief ClientNotification. | ||||
| */ | */ | ||||